Typescript条件类型传入联合泛型避免分发的实现方法及原理解析
问题1 解决方案
要阻止条件类型的联合分发行为,只需要把条件类型两端的泛型参数包裹在元组中即可,修改后的TTypeWithConditional定义如下:
type TTypeWithConditional<T> = [T] extends [string] ? TObjectWithGeneric<T> : never;
修改后再传入TArbitraryUnion,得到的类型就和TType2完全一致,为TObjectWithGeneric<"a" | "b">。
问题2 底层原因
两者类型不同的核心是TypeScript的分布式条件类型特性:
- 当条件类型中的待检查类型是没有被任何包装的裸类型参数时,只要传入的泛型实参是联合类型,就会触发自动分发逻辑:会把联合的每个成员单独带入条件类型计算,最后把所有结果合并为联合类型返回。
你的TTypeWithConditional中T extends string的T就是裸类型参数,传入"a" | "b"后会分别计算"a" extends string和"b" extends string的结果,最后合并为TObjectWithGeneric<"a"> | TObjectWithGeneric<"b">,也就是你看到的TType1。 TTypeWithoutConditional不存在条件类型结构,也没有触发分发的逻辑,联合类型会作为整体直接代入泛型参数,所以最终得到的是TObjectWithGeneric<"a" | "b">。
内容的提问来源于stack exchange,提问作者James Flight
相关产品推荐
相关产品推荐

