admin管理员组文章数量:1295729
I have some experimental code that inherits from Array<T>
...
class SuperArray<T> extends Array<T> {
constructor(...items) {
super(...items);
}
public clear(): void {
while (this.length > 0) {
this.pop();
}
}
}
var array = new SuperArray("Matt", "Mark", "Luke", "John");
array.clear();
Playground
I've added the clear
method just to illustrate the problem. When this is piled and run in the browser, I get...
TypeError: array.clear is not a function
How is this pletely valid code in TypeScript, but not valid in JavaScript, and is there a way to fix this?
I have some experimental code that inherits from Array<T>
...
class SuperArray<T> extends Array<T> {
constructor(...items) {
super(...items);
}
public clear(): void {
while (this.length > 0) {
this.pop();
}
}
}
var array = new SuperArray("Matt", "Mark", "Luke", "John");
array.clear();
Playground
I've added the clear
method just to illustrate the problem. When this is piled and run in the browser, I get...
TypeError: array.clear is not a function
How is this pletely valid code in TypeScript, but not valid in JavaScript, and is there a way to fix this?
Share asked Jan 11, 2017 at 14:04 Matthew LaytonMatthew Layton 42.4k57 gold badges207 silver badges336 bronze badges3 Answers
Reset to default 8BTW this is a breaking change in TS2.1
This TS documentation has a remendation for a changing the prototype in your constructor
constructor(...items) {
super(...items);
Object.setPrototypeOf(this, SuperArray.prototype);
}
Your code piles into this when targeting es5
:
var SuperArray = (function (_super) {
__extends(SuperArray, _super);
function SuperArray() {
var items = [];
for (var _i = 0; _i < arguments.length; _i++) {
items[_i] = arguments[_i];
}
return _super.apply(this, items) || this;
}
SuperArray.prototype.clear = function () {
while (this.length > 0) {
this.pop();
}
};
return SuperArray;
}(Array));
var array = new SuperArray("Matt", "Mark", "Luke", "John");
array.clear();
It's not possible to extend native objects like that, which is why you're getting this error.
If you'll target es6
then the piled js will look like this:
class SuperArray extends Array {
constructor(...items) {
super(...items);
}
clear() {
while (this.length > 0) {
this.pop();
}
}
}
var array = new SuperArray("Matt", "Mark", "Luke", "John");
array.clear();
And that will work just fine (if you run it in a browser that supports es6 classes).
Edit
I'll just paste parts of the article Subclassing builtins in ECMAScript 6 which explains why it can't be done with es5
:
Allocation obstacle: MyArray allocates the wrong kind of object
Array instances are special – the ECMAScript 6 specification calls them exotic. Their handling of the property length can’t be replicated via normal JavaScript. If you invoke the constructor MyArray then an instance of MyArray is created, not an exotic object.Initialization obstacle: MyArray can’t use Array for initialization
It is impossible to hand an existing object to Array via this – it pletely ignores its this and always creates a new instance.
Since Typescript 2.2 you can access new.target
from the constructor.
Thus you can make the following call after having called super()
:
Object.setPrototypeOf(this, new.target.prototype);
It should solve the propotype chain issue
本文标签: javascriptTypeScript ArrayltTgt inheritanceStack Overflow
版权声明:本文标题:javascript - TypeScript Array<T> inheritance - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741623185a2388931.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论