rivo
Version:
🤖 The ultimate library you need for composable type-level programming in TypeScript, powered by HKT.
120 lines (113 loc) • 3.81 kB
TypeScript
import type { Args, Call1W, Fn1, GenericFn, GenericResolver, Param0, Return } from "../HKT";
type GetReturnFnParamType<Branches extends readonly Fn1[]> =
Branches extends readonly [infer Head extends Fn1, ...infer Tail extends Fn1[]] ?
readonly [Param0<Head>, ...GetReturnFnParamType<Tail>]
: readonly [];
type GetReturnFnReturnTypeReadonly<Branches extends readonly Fn1[]> =
Branches extends readonly [infer Head extends Fn1, ...infer Tail extends Fn1[]] ?
readonly [Return<Head>, ...GetReturnFnReturnTypeReadonly<Tail>]
: readonly [];
type GetReturnFnReturnTypeWritable<Branches extends readonly Fn1[]> =
Branches extends readonly [infer Head extends Fn1, ...infer Tail extends Fn1[]] ?
[Return<Head>, ...GetReturnFnReturnTypeWritable<Tail>]
: [];
type CallBranchesReadonly<Branches extends readonly Fn1[], TS extends readonly unknown[]> =
Branches extends readonly [infer HeadBranch extends Fn1, ...infer TailBranch extends Fn1[]] ?
TS extends readonly [infer Head, ...infer Tail] ?
readonly [Call1W<HeadBranch, Head>, ...CallBranchesReadonly<TailBranch, Tail>]
: never
: readonly [];
type CallBranchesWritable<Branches extends readonly Fn1[], TS extends unknown[]> =
Branches extends readonly [infer HeadBranch extends Fn1, ...infer TailBranch extends Fn1[]] ?
TS extends readonly [infer Head, ...infer Tail] ?
[Call1W<HeadBranch, Head>, ...CallBranchesWritable<TailBranch, Tail>]
: never
: [];
type FilterOutNevers<TS extends readonly unknown[]> =
TS extends readonly [infer Head, ...infer Tail] ?
[Head] extends [never] ?
FilterOutNevers<Tail>
: readonly [Head, ...FilterOutNevers<Tail>]
: TS;
interface Resolver<
InputType extends readonly unknown[],
ReturnTypeReadonly extends readonly unknown[],
ReturnTypeWritable extends unknown[],
> extends GenericResolver<1> {
on_: () => [[InputType], ReturnTypeReadonly];
on1: ([xs]: Args<this>) => [
[],
typeof xs extends unknown[] ? ReturnTypeWritable : ReturnTypeReadonly,
];
}
/**
* [Fn] Map each element of a tuple by a list of branching functions and returns a new tuple.
*
* Sig: `<A, B, ..., X1, X2, ...>(...branches: [(a: A) => X1, (b: B) => X2, ...]) => (xs: [A, B, ...]) => [X1, X2, ...]`
*/
export interface MapEachFn<
Branch1 extends Fn1,
Branch2 extends Fn1,
Branch3 extends Fn1 = never,
Branch4 extends Fn1 = never,
Branch5 extends Fn1 = never,
Branch6 extends Fn1 = never,
Branch7 extends Fn1 = never,
Branch8 extends Fn1 = never,
Branch9 extends Fn1 = never,
Branch10 extends Fn1 = never,
Branch11 extends Fn1 = never,
Branch12 extends Fn1 = never,
Branch13 extends Fn1 = never,
Branch14 extends Fn1 = never,
Branch15 extends Fn1 = never,
Branch16 extends Fn1 = never,
> extends GenericFn<
[
Branch1,
Branch2,
Branch3,
Branch4,
Branch5,
Branch6,
Branch7,
Branch8,
Branch9,
Branch10,
Branch11,
Branch12,
Branch13,
Branch14,
Branch15,
Branch16,
] extends infer Branches extends readonly Fn1[] ?
Resolver<
GetReturnFnParamType<FilterOutNevers<Branches>>,
GetReturnFnReturnTypeReadonly<FilterOutNevers<Branches>>,
GetReturnFnReturnTypeWritable<FilterOutNevers<Branches>>
>
: never
> {
def: ([xs]: Args<this>) => [
Branch1,
Branch2,
Branch3,
Branch4,
Branch5,
Branch6,
Branch7,
Branch8,
Branch9,
Branch10,
Branch11,
Branch12,
Branch13,
Branch14,
Branch15,
Branch16,
] extends infer Branches extends readonly Fn1[] ?
typeof xs extends unknown[] ?
CallBranchesWritable<FilterOutNevers<Branches>, typeof xs>
: CallBranchesReadonly<FilterOutNevers<Branches>, typeof xs>
: never;
}