2016-03-01 65 views
3

而与打字稿我遇到了那么以下有趣的现象玩耍:在Typscript扩展阵列打破构造

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的章节Typescript中的新内容表明应该可以像打字稿1.6中那样扩展本地数组类型。 另外,我没有在脚本语言参考中找到任何内容, 解释了这种行为。

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

我真的没有看到这里出了什么问题,我开始怀疑打字稿错误。 或至少某种类型的无证延长阵列的限制。

关于这里出了什么问题的任何建议?

+0

有关此问题,请在https://github.com/Microsoft/TypeScript/issues/7340处打开问题。 – LongHairedHacker

+0

请参阅http://perfectionkills.com/how-ecmascript-5-still-does-not-allow-to-subclass-an-array/ –

回答

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似乎暗示子类的构造函数应该按照你期望的方式工作。更奇怪的是,我似乎得到不一致的结果测试子类是否是一个Array使用the methods described here时:

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

我建议在开幕TypeScript GitHub repository的问题。即使这是预期的行为,官方文档也会产生误导,应该澄清当本地对象被分类时究竟会发生什么。

+0

感谢您的答案我已经注意到,扩展数组更多的是一个对象而不是数组,但我不认为它是重要的(因为数组也可以被看作是具有数字作为属性名称的对象)。另外,我认为推送仍然适用于像数据结构这样的对象是很奇怪的。我会提交一个错误。 – LongHairedHacker

+0

@LongHairedHacker酷,你可以发布一个问题的链接,一旦你创建它?我对如何解决问题感兴趣。 –