如何在TypeScript中创建泛型参数与另一类泛型参数匹配的泛型类?
如何在TypeScript中创建泛型参数与另一类泛型参数匹配的泛型类?
我完全懂你的需求——就是想让Instance这个泛型类能自动和Template的泛型类型绑定,不用每次都手动传两个重复的泛型参数,只需要指定Template<T>就能让Instance对应上T类型对吧?其实用TypeScript的条件类型和infer关键字就能轻松搞定,我给你一步步拆解:
首先,咱们先把基础的Template类补全,确保它的getInstance方法能返回正确的Instance实例:
class Template<T> { constructor(private generator: () => T) {} getInstance(): Instance<Template<T>> { // 生成对应的值并传入Instance return new Instance(this.generator()) as Instance<Template<T>>; } }
接下来,我们需要一个工具类型来从Template的类型里提取出它的泛型参数,这里就要用到infer关键字,它能帮我们“推断”出泛型里的具体类型:
// 这个工具类型会从Template<U>里自动提取出U的类型 type ExtractTemplateType<T> = T extends Template<infer U> ? U : never;
最后,重新定义Instance类,让它的泛型参数约束为Template的任意实例类型,然后用上面的工具类型自动关联到对应的U类型:
class Instance<T extends Template<any>> { value: ExtractTemplateType<T>; constructor(value: ExtractTemplateType<T>) { this.value = value; } }
现在你就可以完全按照自己的理想写法来使用了:
// 手动指定类型的写法,和你想要的完全一致 const generatedNumber: Instance<Template<number>> = new Template<number>(() => 42).getInstance(); // 甚至TypeScript能自动推导类型,连Instance的类型都不用手动写 const autoGenerated = new Template<number>(() => 42).getInstance(); // autoGenerated的类型会被自动识别为Instance<Template<number>>
这样做的好处是,Instance和Template的泛型类型会始终保持匹配,如果你把Template的泛型改成string,Instance的value类型也会自动变成string,完全不用手动修改。
内容来源于stack exchange
相关产品推荐
相关产品推荐

