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

TypeScript如何从联合类型提取单个类型?解析PopUnion工作原理

如何从TypeScript联合类型中提取单个成员?

假设我们有一个联合类型(比如1 | 2 | 3),想要实现一个PopUnion工具类型,从中提取出联合的最后一个成员(比如PopUnion<1|2|3>返回3),你提到的实现代码如下:

type UnionToIntersection<T> = (T extends any ? (x: T) => void : never) extends (x: infer U) => void ?  U : never
type PopUnion<T> = UnionToIntersection<T extends any ? (x: T) => void : never> extends (x: infer U) => void ? U : never

下面拆解PopUnion的工作原理:

1. 把联合类型展开为函数联合

当T是联合类型时,T extends any ? (x: T) => void : never会触发分布式条件类型——TypeScript会自动把联合的每个成员单独代入条件,生成一个函数类型的联合。
比如T = 1|2|3时,这一步会得到:
(x: 1) => void | (x: 2) => void | (x: 3) => void

2. 将函数联合转成交叉类型

UnionToIntersection的作用是把上述函数联合类型转换为交叉类型。这一步利用了TypeScript的函数参数逆变特性:在条件类型中推断函数参数时,联合类型会被解析为交叉类型。
对于上面的例子,转换后的交叉类型是:
(x: 1) => void & (x: 2) => void & (x: 3) => void

3. 从交叉函数类型中推断参数类型

当我们把交叉后的函数类型匹配(x: infer U) => void时,TypeScript的类型推断会取交叉类型中最后一个函数的参数类型作为U的结果。这是TypeScript的实现细节——对多个函数类型的交叉做参数推断时,会返回最后一个成员的参数类型。
所以对于(x:1)=>void & (x:2)=>void & (x:3)=>void,推断出的U就是3。

需要注意的是,这个工具类型返回的是联合类型中定义顺序的最后一个成员,而非任意随机成员。TypeScript的联合类型在编译时会保留定义顺序,因此结果是稳定的。

内容的提问来源于stack exchange,提问作者Yao Zhao

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 15:45:23