import { Func } from './util' ; import { TypeExt , UnionHandler , VariantsOfUnion , VariantModule , KeysOf , Variant , Property } from './variant' ; /**
 * Built to describe an object with the same keys as a variant but instead of constructors
 * for those objects has functions that handle objects of that type.
 */ export type Handler < T , U = any > = { [ P in keyof T ] : ( variant : T [ P ] ) => U ; } ; /**
 * Either the full handler or the partial set plus 'default'
 */ type WithDefault < T , U = any > = Partial < T > & { default : ( ... args : Parameters < FuncsOnly < T > [ keyof T ] > ) => U ; } | T ; /**
 * Pick just the functions of an object.
 */ type FuncsOnly < T > = { [ P in keyof T ] : T [ P ] extends Func ? T [ P ] : never ; } ; /**
 * The key used to indicate the default handler.
 */ export const DEFAULT_KEY = 'default' ; export type DEFAULT_KEY = typeof DEFAULT_KEY ; /**
 * Catch-all type to express type errors.
 */ export interface VariantError < T > { __error : never ; __message : T ; } ; todo export type Limited < T , U > = Exclude < keyof T , U > extends never ? T : VariantError < [ 'Expected keys of handler' , keyof T , 'to be limited to possible keys' , U ] > ; /**
 * Strip undefined from a union of types.
 */ export type Defined < T > = T extends undefined ? never : T ; param obj param handler returns export function match < T extends Property < 'type' , string > , H extends WithDefault < Handler < VariantsOfUnion < T > > > > ( obj , handler ) ; param obj param handler param { string ? } typeKey returns export function match < T extends Property < K , string > , H extends WithDefault < Handler < VariantsOfUnion < T , K > > > , K extends string = 'type' > ( obj , handler , typeKey ? ) ; param obj param handler param { string ? } typeKey returns { The export function match < T extends Property < K , string > , H extends Partial < Handler < VariantsOfUnion < T , K > > > , E extends ( rest : Exclude < T , TypeExt < K , keyof H > > ) => any , K extends string = 'type' > ( obj , handler , _else , typeKey ? ) ; /**
 * Actual impl
 */ export function match < T extends Property < K , string > , H extends Partial < Handler < VariantsOfUnion < T , K > > > | WithDefault < Handler < VariantsOfUnion < T , K > > > , E extends ( rest : Exclude < T , TypeExt < K , keyof H > > ) => any , K extends string = 'type' > ( obj , handler , _elseOrKey ? , key ? ) { const typeKey = typeof _elseOrKey === 'string' ? _elseOrKey : key ; const typeString = obj [ typeKey ?? 'type' as K ] ; if ( typeString in handler ) { return handler [ typeString ] ?. ( obj as any ) ; } else { if ( _elseOrKey != undefined && typeof _elseOrKey === 'function' ) { return _elseOrKey ( obj as any ) ; } else { if ( 'default' in handler ) { return ( handler as { default ( t ) : any ; } ) . default ( obj ) ; } return undefined ; } } } param literal param handler export function matchLiteral < T extends string , H extends UnionHandler < T > > ( literal , handler ) { return handler [ literal ] ?. ( literal ) ; } type Limit < T , Keys extends string > = { [ P in keyof T ] : P extends Keys ? T [ P ] : never ; } ; export const noop = ( ... _ ) => { } ; param x export const unpack = < T > ( x ) => x . payload ; param x export const just = < T > ( x ) => ( ) => x ;