Reputation: 386
Is it possible to merge all properties in a discriminated union of object types?
As an example, suppose I have the following type:
type UnionType = { name: string; } | { age: number; } | { visible: boolean; }
Is it possible to then merge these into a single type like this:
// Expect: { name: string; age: number; visible: boolean };
type Props = MagicType<UnionType>;
This is essentially the inverse of the Unionize
type from utility-types
.
Upvotes: 6
Views: 2638
Reputation: 327934
You can turn a union into an intersection using the answer to this question, with all the caveats that come with it:
type UnionToIntersection<U> =
(U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never
If you don't like the way { name: string; } & { age: number; } & { visible: boolean; }
looks, you can ask the compiler to reinterpret it as a single object type by using an identity mapping:
type MagicType<U> =
UnionToIntersection<U> extends infer O ? { [K in keyof O]: O[K] } : never;
This gives you the following output:
type Props = MagicType<UnionType>;
/* type Props = {
name: string;
age: number;
visible: boolean;
} */
which is what you want.
Upvotes: 15