Typescript: class MyArray extends Array<number> broken in Typescript 2.1.5

Created on 27 Jan 2017  路  3Comments  路  Source: microsoft/TypeScript



TypeScript Version: 2.1.5

I have just moved from Typescript 1.8.5 to 2.1.5 and classes that extend an Array no longer work.

Code

This is a simple condensed form of the issue

class MyArray extends Array<number> 
{
    put(val: number)
    {
        this.push(val);
    }
}

class Test {
    item1: MyArray;

    constructor()
    {
        this.item1 = new MyArray();
    }
}

Expected behavior:

In TS 1.8 I end up with this JS output -

var MyArray = (function (_super) {
    __extends(MyArray, _super);
    function MyArray() {
        _super.apply(this, arguments);
    }
     MyArray.prototype.put = function (val) {
        this.push(val);
    };
    return MyArray;
}(Array));
var Test = (function () {
    function Test() {
        this.item1 = new MyArray();
    }
    return Test;
}());

Actual behavior:

In TS 2.1.5 I end up with this JS output -

var MyArray = (function (_super) {
    __extends(MyArray, _super);
    function MyArray() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    MyArray.prototype.put = function (val) {
        this.push(val);
    };
    return MyArray;
}(Array));
var Test = (function () {
    function Test() {
        this.item1 = new MyArray();
    }
    return Test;
}());

and the result is that

        let foo = new Test();
        foo.item1.put(1);

ends up with "Object doesn't support property or method 'put'"

Duplicate

Most helpful comment

https://github.com/Microsoft/TypeScript/wiki/FAQ#why-doesnt-extending-built-ins-like-error-array-and-map-work

All 3 comments

https://github.com/Microsoft/TypeScript/wiki/FAQ#why-doesnt-extending-built-ins-like-error-array-and-map-work

It's a shame that I couldn't find that in any of the googling that I tried, since the searches are just swamped with outdated issues.
It's also a shame that the compiler makes no attempt to maybe warn you about this ??

@es5ClassFix()
class MyArray extends Array<number> 
{
    put(val: number)
    {
        this.push(val);
    }
}

Here is useful decorator for extending built-ins like Error, Array etc..

interface Constructor<T> {
    new(...args: any[]): T;
}

export function es5ClassFix(): (target: Constructor<any>) => any {
    return (target: Constructor<any>) => {
        return class extends target {
            constructor(...args: any[]) {
                super(args);
                Object.setPrototypeOf(this, target.prototype);
            }
        };
    };
}

Was this page helpful?
0 / 5 - 0 ratings

Related issues

uber5001 picture uber5001  路  3Comments

MartynasZilinskas picture MartynasZilinskas  路  3Comments

Roam-Cooper picture Roam-Cooper  路  3Comments

manekinekko picture manekinekko  路  3Comments

bgrieder picture bgrieder  路  3Comments