You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 12:53:04