UNPKG

varianter

Version:

Simple variants/tagged unions/discriminated unions in TypeScript

41 lines (40 loc) 1.61 kB
declare type Expand<T> = T extends infer O ? { [K in keyof O]: O[K]; } : never; declare type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never; export declare type UnionToVariantMap<U extends { [key: string]: any; }, C extends keyof U> = Expand<UnionToIntersection<U extends any ? { [K in U[C]]: Expand<Omit<U, C>>; } : never>>; declare type VariantMap = { [key: string]: any; }; declare type MapVariantMap<T extends VariantMap> = { [K in keyof T]: (data: T[K]) => any; }; declare type VariantData<T extends VariantMap> = Expand<{ [K in keyof T]: T[K] extends undefined ? never : T[K]; }[keyof T]>; declare type MapVariantMapLike<T extends VariantMap> = MapVariantMap<T> | (Partial<MapVariantMap<T>> & { _: (data: VariantData<T>) => any; }); declare type MapVariant<T extends VariantMap> = <M extends MapVariantMapLike<T>>(map: M) => { [K in keyof M]: M[K] extends (...args: any) => any ? ReturnType<M[K]> : never; }[keyof M]; declare type VariantMethods<T extends VariantMap> = { map: MapVariant<T>; }; declare type VariantCreatorMap<T extends VariantMap> = { [K in keyof T]: [T[K]] extends [never] ? () => Expand<{ type: K; } & VariantMethods<T>> : (data: T[K]) => Expand<{ type: K; data: T[K]; } & VariantMethods<T>>; }; export declare const createVariant: <T extends VariantMap>() => VariantCreatorMap<T>; export declare type Member<T extends VariantCreatorMap<any>> = Expand<{ [K in keyof T]: ReturnType<T[K]>; }[keyof T]>; export {};