import { KeysOfUnion, Simplify } from "type-fest"; /** * Converts a union (|) into an intersection (&); * only keeps the common keys. * * @example * SimplifyUnion< * | { _type: "TypeA", a: "A" } * | { _type: "TypeB", a: "B" } * > == { * _type: "TypeA" | "TypeB" * } */ export type SimplifyUnion = Pick; /** * Converts a union (|) to an intersection (&); * all keys from all unions are kept intact, and either combined or made optional * @example * Combine< * | { _type: "TypeA", a: "A" } * | { _type: "TypeB", b: "B" } * > => { * _type: "TypeA" | "TypeB"; * a?: "A"; * b?: "B"; * } */ export type Combine = { [P in keyof _Combine]: _Combine[P]; }; type _Combine> = TUnion extends unknown ? // Extend each TUnion with all missing keys: TUnion & Partial, never>> : never; /** * This resolves some performance issues with the default UnionToIntersection implementation. * Through much trial-and-error, it was discovered that `UnionToIntersection` suffers from major performance issues * under the following conditions: * - Only happens in the IDE, not at command line * - The input type is _moderately_ complex; but not when it's extremely complex * * By applying `Simplify` first, we eliminate these performance problems! */ export type UnionToIntersectionFast = UnionToIntersection>; /** * Converts a union (|) to an intersection (&). * (note: the implementation by type-fest results in excessive results) */ type UnionToIntersection = (U extends any ? (x: U) => void : never) extends (x: infer I) => void ? I : never; export {};