Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Array inheritance in ES6 declaration file (lib.es6.d.ts) #10886

Open
ggmod opened this issue Sep 13, 2016 · 3 comments
Open

Array inheritance in ES6 declaration file (lib.es6.d.ts) #10886

ggmod opened this issue Sep 13, 2016 · 3 comments
Labels
Domain: lib.d.ts The issue relates to the different libraries shipped with TypeScript Help Wanted You can do this Suggestion An idea for TypeScript
Milestone

Comments

@ggmod
Copy link

ggmod commented Sep 13, 2016

ES6 supports Array inheritance, but this is not reflected in the TypeScript declaration file (lib.es6.d.ts).

Array functions like 'filter' and 'slice' return an array of the subclass, so the following should compile in TypeScript:

class MyArray extends Array {
    get size() { return this.length; }
}

var x = new MyArray(10).slice();
x.size;

The functions 'reverse', 'concat', 'slice', 'splice', 'filter' should return with the type 'this'.
The 'map' function returns an instance of the subtype too, but it I don't know how that could be represented in TypeScript, as it would require a generic parameter in the return type, something like:
map<U>(callback: (value: T, index: number, array: this) => U): this<U>

Another issue is the static constructors of the Array class, this should compile too:

var x = MyArray.of(1,2,3);
var y = MyArray.from([1,2,3]);
x.size;
y.size;

There are also some additional complications added by the @@species Symbol, which can be used to change the type signature of the subclass to not use 'this' as the return value for functions like 'filter' and 'slice'. So for the following example, the subclass would work how the return types are defined in the declaration file currently:

class MyArray2 extends Array {
    static get [Symbol.species]() { return Array; }
}

Chrome and Node.js both already implement the array inheritance features shown here.

@kitsonk
Copy link
Contributor

kitsonk commented Sep 13, 2016

This is going to be difficult, because TypeScript does not currently allow re-slotting of generics on polymorphic this. See #6223 (which this issue could be a considered a dupe of).

The problem becomes if in a subclass you introduce a different generic slot, how does polymorphic this work? For example you create a subclass that only dealt with arrays of arrays, where the generic T was used in this way T[][]. But the generic slot in Array's this would be T[], how do you express that in a way that always works?

There are more examples in the issue mentioned above as well of where polymorphic this breaks down when combined with generics.

@ggmod
Copy link
Author

ggmod commented Sep 14, 2016

The issue with 'map' is indeed the same as the one discussed in "Polymorphic 'this' and Generics", but all the other problematic Array methods could work correctly by simply returning 'this'.

And the Array.from and Array.of methods produce a separate problem, that is also impossible to represent with current TypeScript syntax as far as I know, because the ArrayConstructor interface would have to be able to refer to the 'this' of the Array interface.

@mhegazy
Copy link
Contributor

mhegazy commented Sep 14, 2016

the static functions can be solved by making Array a class. the issue is we need to have a way to describe a callable constructor (#183), as Array can also be called as a function. unfortunately this proposal has stalled in TC39, but we can do a version of it for ambient declarations. i think this should be tracked separately.

for the rest, adding this in place of T[] should be possible. I believe sort already does this.

@mhegazy mhegazy added Suggestion An idea for TypeScript Help Wanted You can do this labels Sep 14, 2016
@mhegazy mhegazy added this to the Community milestone Sep 14, 2016
@mhegazy mhegazy added the Domain: lib.d.ts The issue relates to the different libraries shipped with TypeScript label Sep 14, 2016
falsandtru added a commit to falsandtru/TypeScript that referenced this issue Oct 1, 2016
falsandtru added a commit to falsandtru/TypeScript that referenced this issue Jan 14, 2017
falsandtru added a commit to falsandtru/TypeScript that referenced this issue Jan 18, 2017
falsandtru added a commit to falsandtru/TypeScript that referenced this issue Jan 19, 2017
@RyanCavanaugh RyanCavanaugh modified the milestones: Community, Backlog Mar 7, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Domain: lib.d.ts The issue relates to the different libraries shipped with TypeScript Help Wanted You can do this Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

4 participants