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

TypeScript能否无需类型守卫访问联合类型的非公共字段?

TypeScript 实现联合类型属性的扁平化访问

你想要的这种直接访问联合类型所有属性(不存在的属性自动转为undefined或报错)的原生语法,TypeScript目前是没有的。不过可以通过自定义类型工具,把原联合类型转换成你期望的扁平化类型,从而实现需求。

实现步骤

  1. 定义一个类型工具,用来把联合类型转换成所有属性的类型联合(包含undefined,当部分分支没有该属性时):
type FlattenUnion<T> = {
  [K in keyof (T extends unknown ? T : never)]: 
    T extends { [P in K]?: infer U } ? U : undefined
};
  1. 用这个工具处理你的原联合类型:
type union = { a: string, b: number, c: string, d: number } | {a: string, b: number, c: number } | {a: string, b: string };

// 生成你期望的扁平化类型
type FlattenedUnion = FlattenUnion<union>;

这个FlattenedUnion等价于:

{
  a: string;
  b: number | string;
  c: string | number | undefined;
  d: number | undefined;
}
  1. 把变量声明为这个扁平化类型,就能实现你要的访问效果:
const foo: FlattenedUnion = {
  a: "test",
  b: 123,
  c: "abc",
  d: 456
};

foo.a; // 类型为 string
foo.b; // 类型为 number | string
foo.c; // 类型为 string | number | undefined
foo.d; // 类型为 number | undefined
foo.e; // 编译报错(不存在该属性)

类型工具原理

  • keyof (T extends unknown ? T : never):通过分布式条件类型,获取联合类型所有分支的所有键的集合;
  • 对于每个键K,再次通过分布式条件类型,提取所有分支中K属性的类型,若某个分支没有K属性,则自动补充undefined,最终合并为该属性的联合类型。

内容的提问来源于stack exchange,提问作者Ákos Vandra-Meyer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 15:43:22