合并 Typescript 中对象类型的可区分联合

cal*_*ung 5 typescript

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

作为一个例子,假设我有以下类型:

type UnionType = { name: string; } | { age: number; } | { visible: boolean; }
Run Code Online (Sandbox Code Playgroud)

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

// Expect: { name: string; age: number; visible: boolean };
type Props = MagicType<UnionType>;
Run Code Online (Sandbox Code Playgroud)

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

jca*_*alz 13

您可以使用此问题的答案将并集转换为交集,并附带所有注意事项:

type UnionToIntersection<U> =
  (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never
Run Code Online (Sandbox Code Playgroud)

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

type MagicType<U> = 
  UnionToIntersection<U> extends infer O ? { [K in keyof O]: O[K] } : never;
Run Code Online (Sandbox Code Playgroud)

这将为您提供以下输出:

type Props = MagicType<UnionType>;
/* type Props = {
    name: string;
    age: number;
    visible: boolean;
} */
Run Code Online (Sandbox Code Playgroud)

这就是你想要的。

Playground 代码链接