Class extended from built-in Array in Typescript 1.6.2 does not update length while using [] operator

后端 未结 2 1959
长情又很酷
长情又很酷 2021-01-03 10:47

it should be possible to extend build-in types in ts 1.6 as I read here:

TypeScript 1.6 adds support for classes extending arbitrary expression that comp

相关标签:
2条回答
  • 2021-01-03 11:26

    Your code translates to this JavaScript code:

    var __extends = (this && this.__extends) || function (d, b) {
        for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
    var ExtendedArray = (function (_super) {
        __extends(ExtendedArray, _super);
        function ExtendedArray() {
            _super.apply(this, arguments);
        }
        return ExtendedArray;
    })(Array);
    var buildinArray = new Array();
    var extendedArray = new ExtendedArray();
    buildinArray.push("A");
    console.log(buildinArray.length); // 1 - OK
    buildinArray[2] = "B";
    console.log(buildinArray.length); // 3 - OK
    extendedArray.push("A");
    console.log(extendedArray.length); // 1 - OK
    extendedArray[2] = "B";
    console.log(extendedArray.length); // 1 - FAIL
    console.dir(extendedArray); // both values, but wrong length
    

    [Playground]

    The problem is that the bracket notation is not copied as part of copying of Array prototype:

    In JavaScript, we can sub-class native data types by extending the native prototypes. This works perfectly with the native String object; but, when it comes to native Arrays, things don't work quite so nicely. If we extend the Array prototype, we inherit the native array functions; but, we no longer have the ability to use bracket notation to set and get indexed values within the given array. Sure, we can use push() and pop() to overcome this limitation; but, if we want to keep the bracket notation feature functional, we have to build on top of an existing array instance rather than truly sub-classing the Array object.

    [Source]

    There is an in-depth discussion and solutions here by Dr. Axel Rauschmayer.

    0 讨论(0)
  • 2021-01-03 11:36

    Extending Array is only supported in ES6 environments, so if you've set the compilerSettings.target of your tsconfig.json to ES3 or ES5 this won't work properly. There are workarounds in ES5 but I'd say it isn't worth the trouble - although you can probably use it in TypeScript since it is a superset of ES5. This book on ES6 explains the situation in more detail.

    0 讨论(0)
提交回复
热议问题