TypeScript:如何从this推断当前类类型而非多态this?
这个问题我之前也踩过坑——TypeScript在类的属性初始化器中,对this的类型推断会优先采用多态this类型(也就是代表当前类或其任意子类的抽象类型),而不是当前类的具体类型(比如你的C类)。这就导致test(this)里的泛型参数T被推断为this,进而让field的类型停留在GenericArgument<this>,而不是我们期望的number。
下面是几种可行的解决办法,你可以根据场景选择:
1. 把属性初始化移到构造函数里
在类的构造函数中,this的类型会被解析为当前类的具体类型(而非多态this),TypeScript能正确推断泛型参数T为C,从而得到number类型:
class C extends A<number> { field: number; constructor() { super(); this.field = test(this); // field类型现在是number } }
2. 用getter替代直接属性赋值
getter函数中的this类型推断会更激进,TypeScript会自动展开GenericArgument<this>为实际的number类型:
class C extends A<number> { get field() { return test(this); // field类型为number } }
注意:这种方式每次访问field都会调用test,如果test是有副作用的函数,要谨慎使用。
3. 显式将this断言为当前类类型
如果一定要在属性初始化器里赋值,可以手动把this断言为当前类的具体类型,强制TypeScript推断正确的泛型参数:
class C extends A<number> { field = test(this as C); // field类型为number }
4. 写一个通用辅助函数避免重复代码
如果有多个类需要处理,写一个简单的辅助函数来提取当前类的具体类型,不用每个类都手动写断言:
function getConcreteInstance<T>(this: T): T { return this; } class C extends A<number> { field = test(getConcreteInstance.call(this)); // field类型为number }
5. 优化泛型类型的解析逻辑
你也可以修改GenericArgument的类型定义,确保它能正确处理多态this类型:
// 优化类型提取逻辑,确保能从多态this中解析出R type GenericArgument<T> = T extends A<infer R> ? R : never; // 或者直接给函数的返回类型加更明确的约束 function test<T extends A<any>>(obj: T): GenericArgument<T> { return obj.something as GenericArgument<T>; } class C extends A<number> { field = test(this); // 现在field类型会被解析为number }
内容的提问来源于stack exchange,提问作者Adam Ogiba
相关产品推荐
相关产品推荐

