如何在TypeScript中使用this<R>泛型并创建该类型的泛型集合?
实现泛型集合的
this类型实例创建 要让Vector.map返回Vector<R>,SpecialisedVector.map返回SpecialisedVector<R>,核心是让newInstance方法正确返回当前类(包括子类)的泛型实例,而非any类型。
解决思路
利用TypeScript的多态this类型和构造函数类型推断,让newInstance方法返回当前类的泛型实例,确保子类调用map时能返回自身类型的实例。
修改后的完整代码
class Vector<T> { items: T[] constructor(...items: T[]) { this.items = items } // 正确返回当前类的泛型实例 newInstance<R>(...items: R[]): this extends Vector<infer _> ? this & { items: R[] } : never { return new (this.constructor as new(...args: R[]) => Vector<R>)(...items) as any } map<R>(op: (v: T, i: number) => R): ReturnType<this['newInstance']<R>> { return this.newInstance(...this.items.map(op)) } } class SpecialisedVector<T> extends Vector<T> { sum(this: SpecialisedVector<number>): number { return this.items.reduce((a, b) => a + b) } } const v = new SpecialisedVector('a', 'b') console.log(v.map((s) => s.length).sum()) // 输出:2
关键说明
newInstance返回类型约束:通过this extends Vector<infer _> ? this & { items: R[] } : never,确保返回实例是当前类(含子类)的类型,且泛型参数替换为R。- 构造函数类型断言:
this.constructor as new(...args: R[]) => Vector<R>告知TypeScript,当前实例的构造函数可接受R类型数组参数,返回对应泛型实例。 map返回类型复用:使用ReturnType<this['newInstance']<R>>直接复用newInstance的返回类型,保证类型一致性。
修改后,SpecialisedVector调用map会返回SpecialisedVector<R>,可正常调用sum方法,同时类型检查完全生效。
内容的提问来源于stack exchange,提问作者Alex Craft
相关产品推荐
相关产品推荐

