如何将TypeScript联合类型转换为交叉类型?附函数类型示例
将联合类型转换为交叉类型的方法
当然有办法实现这个转换!在TypeScript里,我们可以利用分布式条件类型和逆变类型特性来巧妙地把联合类型转换成交叉类型。
核心实现思路
当条件类型作用于联合类型时,TypeScript会自动展开联合类型进行分布式处理;而函数的参数位置属于逆变位置,在这个位置上进行类型推断时,联合类型会被收拢成交叉类型——这就是我们实现转换的关键。
转换工具类型
我们可以定义一个通用的类型工具来完成这个转换:
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
代码解释
让我们拆解一下这个类型的工作流程:
- 第一步:展开联合类型
U extends any ? (k: U) => void : never会把联合类型的每个成员都转换成一个接受该成员作为参数的函数。比如把A | B转换为(k: A) => void | (k: B) => void。 - 第二步:逆变位置推断交叉类型
当我们把这个函数联合类型赋值给((k: infer I) => void)时,TypeScript会在逆变的参数位置推断出I的类型——只有交叉类型才能同时满足所有函数的参数要求,因此最终I就是原联合类型对应的交叉类型。
验证你的例子
用你给出的函数联合类型来测试:
type FunctionUnion = (() => void) | ((p: string) => void); type FunctionIntersection = UnionToIntersection<FunctionUnion>; // 此时 FunctionIntersection 完全等价于 (() => void) & ((p: string) => void)
扩展适用场景
这个工具类型不仅适用于函数联合,对对象等其他类型的联合也同样有效:
type ObjUnion = { a: number } | { b: string }; type ObjIntersection = UnionToIntersection<ObjUnion>; // 等价于 { a: number } & { b: string }
内容的提问来源于stack exchange,提问作者Titian Cernicova-Dragomir
相关产品推荐
相关产品推荐

