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

如何将TypeScript联合类型转换为合并类型:公共键转为联合类型、非公共键转为可选联合类型?

如何将TypeScript联合类型转换为合并类型:公共键转为联合类型、非公共键转为可选联合类型?

这个需求太贴合实际开发场景了!我之前处理第三方API返回类型时也碰到过一模一样的问题,刚好可以用TypeScript的分布式条件类型来实现你要的SomeMergeUtil工具类型。

先直接上可用的解决方案,你可以直接复制使用:

// 先提取联合类型中所有成员的键,合并成一个键联合
type KeysOfUnion<T> = T extends T ? keyof T : never;

// 核心的合并工具类型
type MergeUnion<T> = {
  [K in KeysOfUnion<T>]: T extends { [P in K]: infer V } ? V : undefined;
};

用你的例子测试一下,完全符合预期的效果:

type ThirdPartyUnion = {a: 'success', data: object} | {a: 'error', error: Error};
type MyIntersection = MergeUnion<ThirdPartyUnion>;
// 最终生成的类型:{a: 'success' | 'error', data: object | undefined, error: Error | undefined}

简单拆解一下原理:

  • KeysOfUnion<T>:借助TypeScript的分布式条件类型特性,自动遍历联合类型的每个成员,把每个成员的键提取出来再合并成一个大的键联合。比如你的例子里,它会返回'a' | 'data' | 'error'。
  • MergeUnion<T>:遍历所有收集到的键K,对每个键再次用分布式条件类型检查:如果联合里的成员包含这个键,就提取它的类型V;如果不包含,就返回undefined。这样公共键(比如你的a)会自动把所有成员的对应类型合并成联合,非公共键(data和error)则会变成「自身类型 + undefined」的形式。

你之前尝试的UnionToIntersection之所以达不到效果,是因为它的作用是把联合类型转成交叉类型——比如{a: 'success'} & {a: 'error'}会因为类型冲突变成{a: never},这和你要的“合并所有可能类型”的思路完全相反,所以得换这种「逐个收集键的所有可能类型」的方式。

再给你个更复杂的测试案例验证下:

type TestUnion = {x: number, y: string} | {x: boolean, z: symbol} | {w: bigint};
type TestMerge = MergeUnion<TestUnion>;
// 最终生成的类型:{x: number | boolean, y: string | undefined, z: symbol | undefined, w: bigint | undefined}

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 13:24:31