typescript / expert
Snippet
Union to Intersection Conversion for Contravariant Handler Extraction
By exploiting function argument contravariance in conditional infer positions, this technique transforms a type union A | B into an intersection type A & B. This enables compile-time generation of multi-overload function signatures that must accept all union constituents simultaneously.
snippet.ts
typescript
1
2
3
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;type EventPayloads = { type: 'click'; x: number } | { type: 'hover'; target: string };type CombinedHandler = UnionToIntersection<EventPayloads extends infer E ? (event: E) => void : never>;
Breakdown
1
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
Distributes U into function parameters, causing TypeScript to infer I as an intersection due to contravariance.
2
type EventPayloads = { type: 'click'; x: number } | { type: 'hover'; target: string };
Defines a discriminated union of distinct event payload shapes.
3
type CombinedHandler = UnionToIntersection<EventPayloads extends infer E ? (event: E) => void : never>;
Produces a single function type taking an event parameter that must satisfy both event payloads simultaneously.