如何简化TypeScript含隐含泛型的类A的声明与实例化?
当然可以!用条件类型提取泛型参数就行
你完全可以简化类A的泛型声明,只需要指定TB就能让TypeScript自动推导TC的类型——核心思路是用条件类型+infer关键字从TB中提取它的泛型参数TC。
具体实现代码
先假设你的基础类型是这样的:
// 基础接口和类的定义 interface TD<TB, TC> { make(): TC; } class B<TC> {}
接下来修改类A的泛型声明,添加一个用来提取TC的条件类型:
// 定义条件类型,从TB中提取它继承的B类的泛型参数TC type ExtractTCFromTB<TB> = TB extends B<infer TC> ? TC : never; // 类A只需要接收TB泛型参数,TC通过条件类型自动推导 export class A<TB extends B<any>> implements TD<TB, ExtractTCFromTB<TB>> { make(): ExtractTCFromTB<TB> { // 这里替换成你实际的TC实例化逻辑,示例用类型断言占位 return {} as ExtractTCFromTB<TB>; } }
实例化验证
现在你可以按照想要的方式实例化,TypeScript会自动推导TC的类型:
class CTest {} class BTest extends B<CTest> {} // 只需要指定TB,TC自动推导为CTest const a = new A<BTest>(); const result = a.make(); // result的类型是CTest,完全符合预期!
原理说明
ExtractTCFromTB<TB>是一个条件类型:当TB符合B<TC>的结构时,infer关键字会自动捕获TC的类型并返回;- 类
A的泛型约束TB extends B<any>保证了TB一定是B类的子类,所以ExtractTCFromTB<TB>永远不会返回never; - 实现
TD<TB, TC>接口时,直接用提取后的ExtractTCFromTB<TB>代替显式声明的TC即可。
如果你的B类有多个泛型参数,只需要调整infer的位置,比如TB extends B<infer TC, infer TD> ? TC : never就能提取第一个泛型参数,非常灵活。
内容的提问来源于stack exchange,提问作者Levi
相关产品推荐
相关产品推荐

