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

如何合并TypeScript联合类型?实现指定类型结构需求

解决方案:将对象联合类型转换为合并后的类型

基础场景:合并共享属性为联合类型

你定义的两个类型:

type a = { a: "hi", b: number }
type b = { a: "bye", b: number }

想要得到合并后的类型{ a: "hi" | "bye", b: number },使用UnionToIntersection会得到never是因为交叉类型会将互斥的字面量属性合并为never:"hi" & "bye"本身就是不可能的类型,最终整个交叉类型变为never,这不符合你的需求。

可以使用以下工具类型实现目标:

type MergeUnion<T> = {
  [K in keyof T]: T[K]
}

// 测试
type c = MergeUnion<a | b>
// 推导结果:{ a: "hi" | "bye"; b: number; }

这个类型的逻辑是:遍历联合类型的所有公共键,每个键的类型取联合中所有成员对应键的类型的联合,自动将共享属性的不同值合并为联合类型,相同类型的属性保持不变。


补充场景:合并联合类型为含可选独有属性的类型

对于以下联合类型:

type o = {
  type: "bar";
  foo: string;
  bar: number;
} | {
  type: "baz";
  foo: string;
  baz: boolean;
}

想要转换为包含必选共享属性、可选独有属性的类型,可以使用更复杂的工具类型:

// 提取联合类型的所有键
type AllKeys<T> = T extends unknown ? keyof T : never;

// 合并联合类型,共享属性必选,独有属性可选
type MergeUnionWithOptional<T> = {
  // 处理所有联合成员共享的必选属性
  [K in keyof T]: T[K]
} & {
  // 处理仅部分成员拥有的可选属性
  [K in Exclude<AllKeys<T>, keyof T>]?: T extends Record<K, infer V> ? V : never
} extends infer Merged ? { [K in keyof Merged]: Merged[K] } : never;

// 测试
type MergedO = MergeUnionWithOptional<o>;
// 推导结果:{
//   type: "bar" | "baz";
//   foo: string;
//   bar?: number;
//   baz?: boolean;
// }

逻辑说明:

  1. AllKeys<T>:遍历联合类型的每个成员,收集所有可能的键,得到所有键的联合集合;
  2. 第一部分[K in keyof T]:筛选出所有联合成员都包含的键,作为必选属性,类型为对应键在联合中的类型联合;
  3. 第二部分Exclude<AllKeys<T>, keyof T>:筛选出仅部分成员拥有的键,标记为可选属性,类型为对应键在包含它的成员中的类型;
  4. 最后交叉两部分并展开,得到结构清晰的合并类型。

内容的提问来源于stack exchange,提问作者Islam Y-

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 19:20:07