import type { Args, Call0, Call1W, Fn0, Fn1 } from "./HKT"; import type { List } from "./List"; import type { None, Option, Some } from "./Option"; export interface When, Then extends Fn0 | Fn1> extends Fn1> { _tag: "When"; def: ([value]: Args) => Call1W extends true ? Some : Call1W> : None; } export interface Otherwise extends Fn1> { _tag: "Otherwise"; def: ([value]: Args) => Else extends Fn0 ? Call0 : Call1W; } type _IsAnyOtherwise = TS extends readonly [infer Head, ...infer Tail] ? [Head] extends [never] ? _IsAnyOtherwise : Head extends Otherwise ? true : _IsAnyOtherwise : false; type _ExcludeNevers = TS extends readonly [infer Head, ...infer Tail] ? [Head] extends [never] ? _ExcludeNevers : readonly [Head, ..._ExcludeNevers] : TS; type _Decide = FS extends readonly [infer F] ? F extends Otherwise ? Call1W : F extends When ? Call1W : never : FS extends readonly [infer F, ...infer Tail] ? F extends Otherwise ? Call1W : F extends When ? Call1W extends infer R ? R extends None ? _Decide : _IsAnyOtherwise extends true ? R extends Some ? R : never : R : never : never : never; type _ExtractFnReturnType = F extends F ? F extends Fn0 ? R : F extends Fn1 ? R : never : never; type _ExtractReturnType = T extends T ? T extends When ? _ExtractFnReturnType : T extends Otherwise ? _ExtractFnReturnType : never : never; export interface Decide< A extends When, B extends When | Otherwise, // prettier-ignore C extends (_IsAnyOtherwise<[A, B]> extends true ? never : When | Otherwise) = never, // prettier-ignore D extends (_IsAnyOtherwise<[A, B, C]> extends true ? never : When | Otherwise) = never, // prettier-ignore E extends (_IsAnyOtherwise<[A, B, C, D]> extends true ? never : When | Otherwise) = never, // prettier-ignore F extends (_IsAnyOtherwise<[A, B, C, D, E]> extends true ? never : When | Otherwise) = never, // prettier-ignore G extends (_IsAnyOtherwise<[A, B, C, D, E, F]> extends true ? never : When | Otherwise) = never, // prettier-ignore H extends (_IsAnyOtherwise<[A, B, C, D, E, F, G]> extends true ? never : When | Otherwise) = never, // prettier-ignore I extends (_IsAnyOtherwise<[A, B, C, D, E, F, G, H]> extends true ? never : When | Otherwise) = never, // prettier-ignore J extends (_IsAnyOtherwise<[A, B, C, D, E, F, G, H, I]> extends true ? never : When | Otherwise) = never, // prettier-ignore K extends (_IsAnyOtherwise<[A, B, C, D, E, F, G, H, I, J]> extends true ? never : When | Otherwise) = never, // prettier-ignore L extends (_IsAnyOtherwise<[A, B, C, D, E, F, G, H, I, J, K]> extends true ? never : When | Otherwise) = never, // prettier-ignore M extends (_IsAnyOtherwise<[A, B, C, D, E, F, G, H, I, J, K, L]> extends true ? never : When | Otherwise) = never, // prettier-ignore N extends (_IsAnyOtherwise<[A, B, C, D, E, F, G, H, I, J, K, L, M]> extends true ? never : When | Otherwise) = never, > extends Fn1< unknown, _IsAnyOtherwise<[A, B, C, D, E, F, G, H]> extends true ? _ExtractReturnType<_ExcludeNevers<[A, B, C, D, E, F, G, H, I, J, K, L, M, N]>[number]> : Option<_ExtractReturnType<_ExcludeNevers<[A, B, C, D, E, F, G, H, I, J, K, L, M, N]>[number]>> > { def: ([value]: Args) => _Decide< typeof value, _ExcludeNevers<[A, B, C, D, E, F, G, H, I, J, K, L, M, N]> >; }