Union types allow a value to be one of several types, while intersection types combine multiple types into a single type. In some scenarios, you may need to transform a union type into an intersection type.
- Convert a union type into an intersection type.
- Use distributive conditional types for the transformation.
- Preserve the properties of all types in the resulting intersection.
Union Type
A union type allows a variable to hold one of several types using the | operator.
type Animal = "Dog" | "Cat" | "Bird";- Animal can be "Dog", "Cat", or "Bird".
Intersection Type
An intersection type combines multiple types into one using the & operator. A value must satisfy all the combined types.
type Person = { name: string } & { age: number };- Person must contain both name and age properties.
Using Distributive Conditional Types
A distributive conditional type applies a conditional type separately to each member of a union. This behavior can be combined with function parameter inference to transform a union type into an intersection type.
Example:
type UnionToIntersection<U> =
(U extends unknown ? (arg: U) => void : never) extends
(arg: infer I) => void
? I
: never;
// Example usage
type UnionType = { a: number } | { b: string } | { c: boolean };
type IntersectionType = UnionToIntersection<UnionType>;
const myObject: IntersectionType = {
a: 42,
b: "hello",
c: true
};
console.log(myObject);
Output:
{
"a": 42,
"b": "hello",
"c": true
}
U extends unknowndistributes the conditional type over each member of the union.- Each union member is converted into a function parameter type.
infer Iextracts the intersection of those parameter types.- The resulting
IntersectionTyperequires all properties from the original union members.