You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript中如何将交叉类型转为联合类型以获取重载函数

TypeScript交叉类型转联合类型实现方案

TypeScript支持将交叉类型转换为联合类型,尤其是你提到的重载函数场景(函数交叉类型),可以通过类型工具实现转换,不过要注意普通对象交叉类型和函数交叉类型的差异。

一、重载函数(函数交叉类型)的转换实现

重载函数在TS里确实是以多个函数类型的交叉形式存在的,要把它拆成联合类型,可以用递归条件类型结合元组转换:

类型工具代码

// 提取重载函数的所有签名到元组
type Overloads<T> = 
  T extends { (...args: infer A1): infer R1; (...args: infer A2): infer R2; (...args: infer A3): infer R3; (...args: infer A4): infer R4 }
    ? [(...args: A1) => R1, (...args: A2) => R2, (...args: A3) => R3, (...args: A4) => R4]
  : T extends { (...args: infer A1): infer R1; (...args: infer A2): infer R2; (...args: infer A3): infer R3 }
    ? [(...args: A1) => R1, (...args: A2) => R2, (...args: A3) => R3]
  : T extends { (...args: infer A1): infer R1; (...args: infer A2): infer R2 }
    ? [(...args: A1) => R1, (...args: A2) => R2]
  : T extends { (...args: infer A1): infer R1 }
    ? [(...args: A1) => R1]
  : never;

// 将元组转换为联合类型
type IntersectionToUnion<T> = Overloads<T>[number];

测试示例(重载函数场景)

// 定义一个重载函数类型
type OverloadedFunc = ((a: number) => string) & ((a: string) => number);

// 转换为联合类型
type FuncUnion = IntersectionToUnion<OverloadedFunc>;
// 结果:((a: number) => string) | ((a: string) => number)

// 验证转换正确性
type Equals<O1, O2> = (<T>(arg: T extends O1 ? T : T) => void) extends (<T>(arg: T extends O2 ? T : T) => void) ? true : false;
type ExceptTrue<T extends true> = T;
type Test = ExceptTrue<Equals<FuncUnion, ((a: number) => string) | ((a: string) => number)>>;
// Test 类型为 true,说明转换正确

二、普通对象交叉类型的说明

你提供的测试案例里,{ a: 1 } & { b: 2 } 本质等价于 { a: 1, b: 2 }——对象交叉类型的语义是合并所有属性。如果硬要把它转成 { a: 1 } | { b: 2 },相当于改变了类型的核心语义(从同时拥有a、b属性变成只拥有其中一个),这种转换不符合TS的类型等价规则,没有内置支持,也不建议这么做。

总结

针对重载函数的交叉类型,用上面的类型工具就能转成函数联合类型,方便你遍历单个重载实现;而普通对象交叉类型的场景,不建议做这种语义不符的转换。

内容的提问来源于stack exchange,提问作者高厉害

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 21:15:35