I'd like to add some functions to the Array class (I'd rather not have them as functions external to the class since it would ideally be discoverable when typing . following the object). This is what I have so far:
export class List<T> extends Array<T> {
constructor(items?: Array<T>) {
super(...items)
Object.setPrototypeOf(this, List.prototype);
}
get first(): T {
return this[0]
}
}
this runs fine:
const list = new List([1,2,3]);
console.log(list.first)
but if I try to run this:
const list = new List([1,2,3]);
console.log(list.map(x=>x*2))
I get the following error:
super(...items)
^
TypeError: Found non-callable @@iterator
Ideally I would get an object back that is equivalent to new List(this.map(x=>x*2)) How can I extend the Array class without having to rewrite all the methods of Array?
There is no need to set the prototype. The error occurs because the constructor runs a second time when the map is called and the length of the array is passed as an argument, so when you try to spread the argument on the super call, it throws an error because a number is not iterable.
Why does it happen? No idea! I do not have enough points yet, otherwise I'd put this as a comment! :-)
If you change the constructor to use ... to gather the arguments nothing will blow up: