首页 > 解决方案 > 在 Typescript 中合并对象类型的区分联合

问题描述

是否可以在对象类型的区分联合中合并所有属性?

例如,假设我有以下类型:

type UnionType = { name: string; } | { age: number; } | { visible: boolean; }

是否可以将它们合并为一个类型,如下所示:

// Expect: { name: string; age: number; visible: boolean };
type Props = MagicType<UnionType>;

这本质上是Unionizefrom 类型的逆utility-types

标签: typescript

解决方案


您可以使用此问题的答案将联合变成交叉点,并附带所有注意事项:

type UnionToIntersection<U> =
  (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never

如果您不喜欢这种方式,您可以要求编译器通过使用标识映射{ name: string; } & { age: number; } & { visible: boolean; }将其重新解释为单个对象类型:

type MagicType<U> = 
  UnionToIntersection<U> extends infer O ? { [K in keyof O]: O[K] } : never;

这将为您提供以下输出:

type Props = MagicType<UnionType>;
/* type Props = {
    name: string;
    age: number;
    visible: boolean;
} */

这就是你想要的。希望有帮助;祝你好运!

Playground 代码链接


推荐阅读