3 回答

TA貢獻1780條經驗 獲得超1個贊
更新的答案
要回答您修改后的問題,TypeScript 不允許您擴展內置函數Array
等Error
。原因寫在這里。
在 ES2015 中,返回對象的構造函數隱式地將 this 的值替換為 super(...) 的任何調用者。生成的構造函數代碼有必要捕獲 super(...) 的任何潛在返回值并將其替換為這個。
因此,子類化 Error、Array 和其他類可能不再按預期工作。這是由于Error、Array等構造函數使用了ECMAScript 6的new.target來調整原型鏈;但是,在 ECMAScript 5 中調用構造函數時無法確保 new.target 的值。默認情況下,其他下層編譯器通常具有相同的限制。
所以如果你必須在 ES5 環境下擴展內置Array
,那么你可以嘗試使用 Babel 來編譯你的代碼。但是請注意,它具有此處所述的限制。
由于 ES5(對于 transform-classes 插件)的限制,諸如 Date、Array、DOM 等內置類不能被正確地子類化。你可以嘗試使用基于 Object.setPrototypeOf 和 Reflect.construct 的 babel-plugin-transform-builtin-extend,但它也有一些限制。
舊答案
雖然代碼本身可以很好地找到并且在瀏覽器中也可以正常執行,但我認為您遇到的錯誤是由于 TypeScript 編譯器造成的。
對于源代碼
interface Animal {
name: string;
weight: number
}
class AnimalCollection extends Array <Animal> {
constructor(name: string, ...items: Animal[]) {
super(...items);
Object.defineProperty(this, 'name', {
enumerable: false,
writable: false,
value: name
})
}
findAnimal(name:string): Animal | null {
return this.find(a => a.name === name) || null;
}
}
const animalsArray = [
{name: 'TD-23', weight: 60},
{name: 'TD-25', weight: 50},
{name: 'TXD-26', weight: 120},
{name: 'TYD-26', weight: 40}
];
const animals = new AnimalCollection('Deers', ...animalsArray)
console.log(animals.findAnimal('TD-23'));
如果編譯器目標選項設置為ES5,那么它會生成破壞實現的代碼。它生成的代碼是
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __spreadArrays = (this && this.__spreadArrays) || function () {
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
for (var r = Array(s), k = 0, i = 0; i < il; i++)
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
r[k] = a[j];
return r;
};
var AnimalCollection = /** @class */ (function (_super) {
__extends(AnimalCollection, _super);
function AnimalCollection(name) {
var items = [];
for (var _i = 1; _i < arguments.length; _i++) {
items[_i - 1] = arguments[_i];
}
var _this = _super.apply(this, items) || this;
Object.defineProperty(_this, 'name', {
enumerable: false,
writable: false,
value: name
});
return _this;
}
AnimalCollection.prototype.findAnimal = function (name) {
return this.find(function (a) { return a.name === name; }) || null;
};
return AnimalCollection;
}(Array));
var animalsArray = [
{ name: 'TD-23', weight: 60 },
{ name: 'TD-25', weight: 50 },
{ name: 'TXD-26', weight: 120 },
{ name: 'TYD-26', weight: 40 }
];
var animals = new (AnimalCollection.bind.apply(AnimalCollection, __spreadArrays([void 0, 'Deers'], animalsArray)))();
console.log(animals.findAnimal('TD-23'));
但是,如果我們將targetin設置tsconfig.json為等于或大于ES2015,那么它生成的代碼是
"use strict";
class AnimalCollection extends Array {
constructor(name, ...items) {
super(...items);
Object.defineProperty(this, 'name', {
enumerable: false,
writable: false,
value: name
});
}
findAnimal(name) {
return this.find(a => a.name === name) || null;
}
}
const animalsArray = [
{ name: 'TD-23', weight: 60 },
{ name: 'TD-25', weight: 50 },
{ name: 'TXD-26', weight: 120 },
{ name: 'TYD-26', weight: 40 }
];
const animals = new AnimalCollection('Deers', ...animalsArray);
console.log(animals.findAnimal('TD-23'));
這當然有效。所以我認為 ES5 或更低版本的 TypeScript 編譯器存在問題,這會破壞實現。我試過使用Babel 進行編譯,它適用于 ES5。

TA貢獻1806條經驗 獲得超8個贊
導致錯誤的是您編寫函數的方式
interface Animal {
name: string;
weight: number
}
class AnimalCollection extends Array <Animal> {
constructor(name, ...items) {
super(...items);
Object.defineProperty(this, 'name', {
enumerable: false,
writable: false,
value: name
})
}
findAnimal:Animal=(name:String)=> {
return this.find(a => a.name === name) || null;
}
}
const animalsArray = [
{name: 'TD-23', weight: 60},
{name: 'TD-25', weight: 50},
{name: 'TXD-26', weight: 120},
{name: 'TYD-26', weight: 40}
];
const animals = new AnimalCollection('Deers', ...animalsArray)
console.log(animals.findAnimal('TD-23'));
// Uncaught TypeError: animals.findAnimal is not a function

TA貢獻1877條經驗 獲得超6個贊
我可以看到你遺漏了一些any,這是對我有用的代碼:
interface Animal {
name: string;
weight: number
}
class AnimalCollection extends Array <Animal> {
constructor(name: string, ...items : Array <Animal>) { // <-- missing types
super(...items);
Object.defineProperty(this, 'name', {
enumerable: false,
writable: false,
value: name
})
}
findAnimal(name : any): Animal|null { // <-- missing null
return this.find(a => a.name === name) || null;
}
}
const animalsArray = [
{name: 'TD-23', weight: 60},
{name: 'TD-25', weight: 50},
{name: 'TXD-26', weight: 120},
{name: 'TYD-26', weight: 40}
];
const animals = new AnimalCollection('Deers', ...animalsArray)
console.log(animals.findAnimal('TD-23'));
但是此代碼生成以下 JS:
"use strict";
class AnimalCollection extends Array {
constructor(name, ...items) {
super(...items);
Object.defineProperty(this, 'name', {
enumerable: false,
writable: false,
value: name
});
}
findAnimal(name) {
return this.find(a => a.name === name) || null;
}
}
const animalsArray = [
{ name: 'TD-23', weight: 60 },
{ name: 'TD-25', weight: 50 },
{ name: 'TXD-26', weight: 120 },
{ name: 'TYD-26', weight: 40 }
];
const animals = new AnimalCollection('Deers', ...animalsArray);
console.log(animals.findAnimal('TD-23'));
這不會產生任何錯誤
添加回答
舉報