Typescript: Declaring a global array extension leads to compiler error

Created on 24 Aug 2018  路  2Comments  路  Source: microsoft/TypeScript

I want to write that array-extension in TypeScript:

if (!Array.prototype.remove) {
    Array.prototype.remove = function <T>(elem: T): T[] {
        return this.filter(e => e !== elem);
    }
}

so I need to declare an interface for it. There's nothing in that file, just:

declare global {
    interface Array<T> {
        remove(elem: T): Array<T>;
    }
}

but the compiler cries:

TS2669: Augumentations for the global scope can only be directly nested in external modules or ambient module declarations

funny is, when I add this line before:

import * as $ from "jquery";

(what has nothing to do with the Array or something - jQuery is not used here), it's okay for the compiler.

What's going on here?

Question

Most helpful comment

What's going on here?

https://www.typescriptlang.org/docs/handbook/modules.html
In TypeScript, just as in ECMAScript 2015, any file containing a top-level import or export is considered a module. Conversely, a file without any top-level import or export declarations is treated as a script whose contents are available in the global scope (and therefore to modules as well).

After adding the import, your file gets treated as a module - and therefore the global scope augmentation is okay. If you leave out the declare global, you automatically augment the global scope:

// file: array.d.ts
interface Array<T> {
    remove(elem: T): Array<T>;
}

// another file:
[].remove(undefined); // works!

All 2 comments

What's going on here?

https://www.typescriptlang.org/docs/handbook/modules.html
In TypeScript, just as in ECMAScript 2015, any file containing a top-level import or export is considered a module. Conversely, a file without any top-level import or export declarations is treated as a script whose contents are available in the global scope (and therefore to modules as well).

After adding the import, your file gets treated as a module - and therefore the global scope augmentation is okay. If you leave out the declare global, you automatically augment the global scope:

// file: array.d.ts
interface Array<T> {
    remove(elem: T): Array<T>;
}

// another file:
[].remove(undefined); // works!

@AlCalzone (nice name!)
...damn... it works. thank you!! should've read the handbook better.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

MartynasZilinskas picture MartynasZilinskas  路  3Comments

uber5001 picture uber5001  路  3Comments

Zlatkovsky picture Zlatkovsky  路  3Comments

wmaurer picture wmaurer  路  3Comments

weswigham picture weswigham  路  3Comments