Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extending Array from TypeScript

What Am I doing wrong in my below code?

I am trying to extend Array on my class MyNumberList and then trying to use it. What I see is that no items seem to be getting added to the list. I get an undefined when I attempt to access the list elements.

P.S I am using TypeScript 1.8.2

class MyNumberList extends Array<number> {

  constructor(...numbers: number[]) {
    // looks like this is not working
    super(...numbers);
  }
}

let statusCodes: MyNumberList = new MyNumberList(10, 20, 30);

console.log(statusCodes[0]);       // printing undefined
console.log(statusCodes.length);   // printing 0
like image 683
codematix Avatar asked Feb 27 '16 17:02

codematix


1 Answers

Arrays cannot be extended in ES5, so the code that the TypeScript compiler produces doesn't work correctly. The code it produces for your constructor is this:

function MyNumberList() {
    var numbers = [];
    for (var _i = 0; _i < arguments.length; _i++) {
        numbers[_i - 0] = arguments[_i];
    }
    _super.apply(this, numbers);
}

...where _super is Array. In the normal course of things, _super.apply(this, numbers) would work just fine, but the Array function behaves differently when it's called as a function than when it's called as a constructor. Babel and other ES2015 (ES6) to ES5 transpilers have the same problem. To properly inherit from an array requires features within the JavaScript engine that just are not present in ES5 engines.

If you change your constructor code to:

constructor(...numbers: number[]) {
  super();
  this.push(...numbers);
}

...it will populate your instance correctly. I can't guarantee how well other features of Array will work, though.

like image 116
T.J. Crowder Avatar answered Nov 17 '22 00:11

T.J. Crowder