TypeScript继承Array后,如何让内置方法返回子类类型?
解决TypeScript继承Array后内置方法返回自定义类型问题
当你继承Array<number>实现自定义数组类时,像slice这类内置方法默认返回number[]而非自定义的MyArray类型,但显式返回this的自定义方法能正常返回MyArray。要解决这个问题,有两种简洁的方案:
方案1:通过Symbol.species统一控制返回类型
Symbol.species是JS内置符号,用于指定派生对象创建时使用的构造函数。在自定义类中定义它,就能让所有内置数组方法自动返回MyArray类型,无需逐个重写方法:
class MyArray extends Array<number> { constructor(...items: number[]) { super(...items); // 修正原型链,确保实例指向自定义类原型 Object.setPrototypeOf(this, MyArray.prototype); } // 指定创建新实例时使用当前类构造函数 static get [Symbol.species]() { return this; } insert(num: number): this { this.push(num); return this; } }
方案2:逐个重写内置方法指定返回类型
如果只需要修改部分方法的返回类型,可以手动重写目标方法,显式声明返回this类型,并将父类方法的返回结果转换为自定义实例:
class MyArray extends Array<number> { constructor(...items: number[]) { super(...items); Object.setPrototypeOf(this, MyArray.prototype); } insert(num: number): this { this.push(num); return this; } // 重写slice方法,返回MyArray类型 slice(start?: number, end?: number): this { const baseResult = super.slice(start, end); return MyArray.from(baseResult) as this; } // 按需重写其他方法,比如map map(callback: (n: number) => number): this { const baseResult = super.map(callback); return MyArray.from(baseResult) as this; } }
验证效果
const myArray = new MyArray(1, 2, 3); const secondArray = myArray.slice(0, 3); // 类型为MyArray const thirdArray = myArray.insert(4); // 类型为MyArray const mappedArray = myArray.map(n => n * 2); // 类型为MyArray(方案1下自动生效,方案2需重写map)
注意事项
- 构造函数中必须添加
Object.setPrototypeOf(this, MyArray.prototype),否则部分场景下super()返回的实例原型可能仍指向Array,导致类型或运行时异常。 - 方案1会影响所有创建新数组的内置方法(如
filter、concat等),方案2更灵活,适合只修改特定方法的场景。
内容的提问来源于stack exchange,提问作者crazyones110
相关产品推荐
相关产品推荐

