type Extend = H extends infer A ? [...T, A] : never; type Flat = TS extends [ infer H, ...infer T ] ? Flat> : R; declare const NoSuchCase: unique symbol; interface NoSuchCaseBug extends Array { [NoSuchCase]: L; } type On = { on: (...key: I extends Flat ? DI : NoSuchCaseBug) => (handler: (...args: Extract>) => DO) => MV>, O | DO>; }; declare const CasesAreNotExhaustive: unique symbol; interface NonExhaustiveBug { [CasesAreNotExhaustive]: L; } type End = [I] extends [never] ? EndInternal : { otherwise: (handle: (...input: I) => DO) => O | DO; end: NonExhaustiveBug; }; type MV = End & On; type EndInternal = { otherwise: (handle: (...input: I) => DO) => O | DO; end: () => O; }; export declare const match: (...args: I) => MV, never>; /** * Convert union to intersection. See https://stackoverflow.com/q/50374908 */ export type Intersect = (T extends unknown ? (x: T) => 0 : never) extends (x: infer R) => 0 ? R : never; /** * Makes types more readable * Example: Unwrap<{ a: 1 } & { b: 2 }> = { a: 1, b: 2 } */ export type Unwrap = T extends infer R ? { [K in keyof R]: R[K]; } : never; type Inputs = I extends { [Z in T]: infer K; } ? K extends string ? Record unknown> : never : never; type Outputs = { [K in keyof O]: (input: never) => O[K]; }; type Handlers = Unwrap>> & Outputs; export declare const makeMakeVisitor: (tag: T) => () => (handlers: Handlers) => (input: Extract) => O[keyof O]; /** * Make visitor for disjoint union (tagged union, discriminated union) */ export declare const makeVisitor: () => (handlers: Handlers) => (input: Extract) => O[keyof O]; export declare const singleton: (key: K, value: V) => Record; export declare const entries: (o: O) => { [K in keyof O]: [K, O[K]]; }[keyof O][]; export declare const keys: (o: O) => (keyof O)[]; export {};