adir kandel
adir kandel

Reputation: 949

typescript linter triggers error when trying to make a polyfill

I'm trying to make some polyfills for my app for different browsers, I have a file that imports other file, when i import it the typescript fails.

If i comment out the - import "../scripts/polyfill_es5" everything works fine,

if i'm including it the script fails and says -

Property 'assignDeep' does not exist on type 'Object'

Why my import breaks the code?

These are my files:

Polyfill.ts:

import "../scripts/polyfill_es5"

interface Object {
    assignDeep: (target: {}, ...sources: any[]) => object;
}

Object.prototype.assignDeep = (target: {}, ...sources: any[]) => { // .length of function is 2
    'use strict';
    if (target == null) { // TypeError if undefined or null
        throw new TypeError('Cannot convert undefined or null to object');
    }

    const to = Object(target);
    let nextSource;

    for (let index = 1; index < sources.length; index++) {
        nextSource = sources[index];

        if (nextSource != null) { // Skip over if undefined or null
            for (const nextKey in nextSource) {
                // Avoid bugs when hasOwnProperty is shadowed
                if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
                    if (typeof to[nextKey] === 'object'
                        && to[nextKey]
                        && typeof nextSource[nextKey] === 'object'
                        && nextSource[nextKey]) {
                        to[nextKey] = Object.assignDeep(Array.isArray(to[nextKey]) ? [] : {}, to[nextKey], nextSource[nextKey]);
                    } else {
                        to[nextKey] = nextSource[nextKey];
                    }
                }
            }
        }
    }
    return to;
};

polyfill_es5.ts:

interface NodeList {
    forEach : (callback : (currentValue : Node, currentIndex : number, listObj : NodeList) => void, thisArg : string|Window) => void;
}

if (typeof NodeList !== 'undefined' && !NodeList.prototype.forEach) {
    NodeList.prototype.forEach = (callback : (currentValue : Node, currentIndex : number, listObj : NodeList) => void, thisArg : string|Window) => {
        thisArg = thisArg || window;
        for (let i = 0; i < this.length; i++) {
            callback.call(thisArg, this[i], i, this);
        }
    };
}

Upvotes: 0

Views: 171

Answers (1)

unional
unional

Reputation: 15599

You need to do global augmentation:

declare global {
  interface Object {
    assignDeep: (target: {}, ...sources: any[]) => object;
  }
}

When a file contains top-level import/export statement, TypeScript compiler will treat the file as a module file. So your interface Object { } is local to the file, not for the global Object.

Upvotes: 2

Related Questions