在Typescript中扩展数组中断构造函数

时间:2016-03-01 15:17:31

标签: arrays constructor typescript

在玩打字稿时,我遇到了有趣的行为:

class ExtArray<U> extends Array<U> {

    constructor(...args : U[]) {
        super(...args);
    }

    public contains(element : U) : boolean {
        var i = this.indexOf(element);
        return i !== -1;
    }
}


var test : ExtArray<string> = new ExtArray("a", "b", "c");

test.push("y");

console.log(test.length); // 1

console.log(test[0]);  // y
console.log(test[1]);  // undefined
console.log("Has a: " + test.contains("a"));  // Has a: false
console.log("Has y: " + test.contains("y"));  // Has y : true

我已将console.log语句的输出添加为注释。 有关可执行示例和javascript代码,请参阅this typescript playground

正如您所看到的那样,传递给构造函数的元素似乎没有添加到数组中。

中的extending expression部分打字稿中的新内容表明应该可以扩展原型Array类型,就像在typescript 1.6中一样。 我也没有在打字稿语言参考中找到任何东西, 这解释了这种行为。

我在这里找到的关于扩展阵列的大多数其他问题至少有一年的历史,并且通常会讨论1.0版本的打字稿,因此建议直接设置原型链。

我真的不知道这里出了什么问题,而且我开始怀疑打字稿错误了。 或者至少某种未记录的限制来扩展数组。

这里出了什么问题?

1 个答案:

答案 0 :(得分:2)

如果你JSON.stringify()你的对象,它会更容易理解发生了什么:

var test : ExtArray<string> = new ExtArray("a", "b", "c");
test.push("y");

// outputs {"0":"y","length":1}
document.writeln(JSON.stringify(test)); 

如果您改为使用本地Array,则生成的对象会有所不同:

var test : Array<string> = new Array("a", "b", "c");
test.push("y");

// outputs ["a","b","c","y"]
document.writeln(JSON.stringify(test));

我同意你的观点,the documentation似乎暗示子类的构造函数应该按照你期望的方式运行。更奇怪的是,在使用the methods described here测试子类是否为Array时,我似乎得到了不一致的结果:

test.constructor === Array // false
test instanceof Array // true
Array.isArray(test) // false

我建议在TypeScript GitHub repository上打开一个问题。即使这是预期的行为,官方文档也会产生误导,并且应该明确当本机对象被子类化时的预期结果。