rivo
Version:
π€ The ultimate library you need for composable type-level programming in TypeScript, powered by HKT.
1,301 lines (1,266 loc) β’ 64.1 kB
TypeScript
import type { Nat } from "./Num";
import type { Add } from "./Num/Nat/Add";
import type { Repeat as RepeatString } from "./Str/Repeat";
import type { Repeat } from "./Tuple/Repeat";
import type { Eq } from "./helpers";
import type { Ord, Show } from "./typeclass";
/**
* Mark a type as a construct type.
*
* It actually does nothing and is only used to make code more readable.
*/
export type Cons<T> = T;
/**
* A type used to represent a type level function (aka. type lambda, or higher-kinded type (HKT)).
*
* It is type safe as long as the `Params` and `Return` are **correct**.
*
* Due to the **contravariant** nature of function inputs, `Params` are represented
* using a function that takes `Params` as input.
*
* **β οΈ Warning:** Some utility types use `Params` and `Return` to provide type safety,
* so **make sure** to use the **correct** `Params` and `Return` when defining a type level function.
*
* @example
* ```typescript
* interface PrependStringFn extends Fn<[string, string], string> {
* def: ([start, s]: Args<this>) => `${typeof start}${typeof s}`;
* }
* type R = $<PrependStringFn, "foo", "bar">;
* // ^?: "foobar"
* ```
*/
export interface Fn<in Params extends unknown[] = never, out Return = unknown> {
readonly Params: (_: Params) => void;
readonly Return: Return;
}
/**
* The **unsafe** version of {@link Fn} (i.e. no type checking with `Params`).
*/
export interface FnW<in Params, out Return>
extends Fn<Params extends unknown[] ? Params : never, Return> {}
/**
* A shorthand for `Fn<[], R>`.
*
* @see {@link Fn}
*/
export interface Fn0<out R = unknown> extends Fn<[], R> {}
/**
* A shorthand for `Fn<[A], R>`.
*
* @see {@link Fn}
*/
export interface Fn1<in A = never, out R = unknown> extends Fn<[A], R> {}
/**
* A shorthand for `Fn<[A, B], R>`.
*
* @see {@link Fn}
*/
export interface Fn2<in A = never, in B = never, out R = unknown> extends Fn<[A, B], R> {}
/**
* A shorthand for `Fn<[A, B, C], R>`.
*
* @see {@link Fn}
*/
export interface Fn3<in A = never, in B = never, in C = never, out R = unknown>
extends Fn<[A, B, C], R> {}
/**
* A shorthand for `Fn<[A, B, C, D], R>`.
*
* @see {@link Fn}
*/
export interface Fn4<in A = never, in B = never, in C = never, in D = never, out R = unknown>
extends Fn<[A, B, C, D], R> {}
interface ApplyFnResolver extends GenericResolver<[Fn, readonly unknown[]], unknown> {
on1_: ([f]: Args<this>) => [[Readonly<ParamsW<typeof f>>], ReturnW<typeof f>];
on_1: ([, args]: Args<this>) => typeof args extends unknown[] ? [[Fn<typeof args>], unknown]
: never;
on11: ([f, args]: Args<this>) => [[], GenericReturnW<typeof f, typeof args>];
on__r: ([, , r]: Args<this>) => [Fn<never, typeof r>, readonly unknown[]];
}
/**
* [Fn] Apply a type level function with the given arguments.
*
* Sig: `<F extends Fn>(f: F, args: Params<F>) => Return<F>`
*/
interface ApplyFn extends GenericFn<ApplyFnResolver> {
def: ([f, args]: Args<this>) => typeof f & {
readonly Args: (_: _DeReadonly<typeof args>) => void;
} extends { readonly def: (...args: never[]) => infer R } ?
R
: never;
}
export namespace Fn {
/**
* [Fn] Apply a type level function with the given arguments.
*
* Sig: `<F extends Fn>(f: F, args: Params<F>) => Return<F>`
*
* @example
* ```typescript
* type R1 = $<Fn.Apply<Str.Concat>, ["a", "b"]>;
* // ^?: "ab"
* type F = Fn.Apply<Str.Concat>;
* type S = Sig<F>;
* // ^?: (x: readonly [string, string]) => number
* type R2 = $<F, ["foo", "bar"]>;
* // ^?: "foobar"
* ```
*/
export type Apply<F extends Fn> = PartialApply<ApplyFn, [F]>;
}
type Evaluate<O> = { [K in keyof O]: O[K] };
/**
* Get the arguments of a type level function and delay the evaluation of the arguments.
*
* It is normally used with `this` in HKT definition.
*
* @see {@link Fn}
*/
export type Args<F extends Fn> = Evaluate<
F extends (
{
readonly Args: (
_: infer Args extends Evaluate<
F extends Fn<infer AS extends unknown[], unknown> ? [...AS, ...never[]] : []
>,
) => void;
}
) ?
Args
: never
>;
/**
* The **unsafe** version of `Args` (i.e. no type checking with `F`).
*
* @see {@link Args}
*/
export type ArgsW<F> = Evaluate<
F extends Fn ?
F extends { readonly Args: (_: infer Args extends Readonly<Params<F>>) => void } ?
Args
: never
: never
>;
/**
* A shorthand for `Args<F>[0]`.
*
* @see {@link Args}
*/
export type Arg0<F extends Fn> = Args<F>[0];
/**
* The **unsafe** version of {@link Arg0} (i.e. no type checking with `F`).
*/
export type Arg0W<F> = ArgsW<F>[0];
/**
* A shorthand for `Args<F>[1]`.
*
* @see {@link Args}
*/
export type Arg1<F extends Fn> = Args<F>[1];
/**
* The **unsafe** version of {@link Arg1} (i.e. no type checking with `F`).
*/
export type Arg1W<F> = ArgsW<F>[1];
/**
* A shorthand for `Args<F>[2]`.
*
* @see {@link Args}
*/
export type Arg2<F extends Fn> = Args<F>[2];
/**
* The **unsafe** version of {@link Arg2} (i.e. no type checking with `F`).
*/
export type Arg2W<F> = ArgsW<F>[2];
/**
* A shorthand for `Args<F>[3]`.
*
* @see {@link Args}
*/
export type Arg3<F extends Fn> = Args<F>[3];
/**
* The **unsafe** version of {@link Arg3} (i.e. no type checking with `F`).
*/
export type Arg3W<F> = ArgsW<F>[3];
/**
* Get the length of the arguments of a type level function.
*/
export type ArgsLength<F extends Fn> = Args<F>["length"];
/**
* Get the parameters of a type level function.
*/
export type Params<F extends Fn> = F extends Fn<infer A> ? A : [];
/**
* The **unsafe** version of {@link Params} (i.e. no type checking with `F`).
*/
export type ParamsW<F> = F extends Fn<infer A> ? A : [];
/**
* A shorthand for `Params<F>[0]`.
*
* @see {@link Params}
*/
export type Param0<F extends Fn> = Params<F>[0];
/**
* The **unsafe** version of {@link Param0} (i.e. no type checking with `F`).
*/
export type Param0W<F> = ParamsW<F>[0];
/**
* A shorthand for `Params<F>[1]`.
*
* @see {@link Params}
*/
export type Param1<F extends Fn> = Params<F>[1];
/**
* The **unsafe** version of {@link Param1} (i.e. no type checking with `F`).
*/
export type Param1W<F> = ParamsW<F>[1];
/**
* A shorthand for `Params<F>[2]`.
*
* @see {@link Params}
*/
export type Param2<F extends Fn> = Params<F>[2];
/**
* The **unsafe** version of {@link Param2} (i.e. no type checking with `F`).
*/
export type Param2W<F> = ParamsW<F>[2];
/**
* A shorthand for `Params<F>[3]`.
*
* @see {@link Params}
*/
export type Param3<F extends Fn> = Params<F>[3];
/**
* The **unsafe** version of {@link Param3} (i.e. no type checking with `F`).
*/
export type Param3W<F> = ParamsW<F>[3];
/**
* Get the length of the parameters of a type level function.
*
* @example
* ```typescript
* type R1 = ParamsLength<Num.ToStr>;
* // ^?: 1
* type R2 = ParamsLength<Str.Prepend>;
* // ^?: 2
* ```
*/
export type ParamsLength<F extends Fn> = Params<F>["length"];
/**
* Get the return type of a type level function.
*/
export type Return<F extends Fn> = F["Return"];
/**
* The **unsafe** version of {@link Return} (i.e. no type checking with `F`).
*/
export type ReturnW<F> = F extends Fn ? F["Return"] : never;
/**
* Add readable names to all types in a tuple.
*/
type _NameAll<TS extends readonly unknown[], Used extends string = never> =
TS extends readonly [infer Head, ...infer Tail] ?
[..._Name<Head, Used>[0], ..._NameAll<Tail, Used | _Name<Head, Used>[1]>]
: [];
type _Name<T, Used extends string = never> =
Eq<T, Show> extends true ? [[s: T], "s"]
: Eq<T, Ord> extends true ? [[o: T], "o"]
: [T] extends [Fn | ((...args: never) => unknown)] ?
"g" extends Used ? [[h: T], "h"]
: "f" extends Used ? [[g: T], "g"]
: [[f: T], "f"]
: Eq<T, readonly Show[]> extends true ? [[ss: T], "ss"]
: Eq<T, Show[]> extends true ? [[sss: T], "ss"]
: Eq<T, readonly Ord[]> extends true ? [[os: T], "os"]
: Eq<T, Ord[]> extends true ? [[oo: T], "os"]
: _IsNotFixedLengthArray<T> extends true ?
T extends readonly (infer U)[] ?
[U] extends [string] ? [[ss: T], "ss"]
: [U] extends [number | bigint] ? [[ns: T], "ns"]
: [U] extends [boolean] ? [[bs: T], "bs"]
: "xs" extends Used ? [[ys: T], "ys"]
: [[xs: T], "xs"]
: never
: [T] extends [string] ? [[s: T], "s"]
: [T] extends [number | bigint] ?
"n" extends Used ?
[[m: T], "m"]
: [[n: T], "n"]
: "y" extends Used ? [[z: T], "z"]
: "x" extends Used ? [[y: T], "y"]
: [[x: T], "x"];
type _IsNotFixedLengthArray<T> =
T extends readonly unknown[] ?
number extends T["length"] ?
true
: false
: false;
/**
* Get the signature of a type level function.
* It should only be used for debugging purposes.
*/
export type Sig<F> = _Sig<F>;
type _Sig<T> = T extends Fn ? (...args: _NameAll<_SigAll<Params<T>>>) => _Sig<ReturnW<T>> : T;
type _SigAll<TS extends readonly unknown[]> =
TS extends readonly [infer Head, ...infer Tail] ? [_Sig<Head>, ..._SigAll<Tail>] : [];
type _DeReadonly<T> = { -readonly [K in keyof T]: T[K] };
/**
* Use with {@link GenericFn} to define a generic type level function.
*/
export type GenericResolver<NOrBaseParams extends Nat | readonly unknown[], BaseReturn = unknown> =
NOrBaseParams extends infer N extends Nat ? Fn<_DeReadonly<Repeat<Add<N, 1>, unknown>>, unknown>
: NOrBaseParams extends infer BaseParams extends readonly unknown[] ?
BaseParams["length"] extends 4 ? TypedGenericResolver4<_DeReadonly<BaseParams>, BaseReturn>
: BaseParams["length"] extends 3 ? TypedGenericResolver3<_DeReadonly<BaseParams>, BaseReturn>
: BaseParams["length"] extends 2 ? TypedGenericResolver2<_DeReadonly<BaseParams>, BaseReturn>
: BaseParams["length"] extends 1 ? TypedGenericResolver1<_DeReadonly<BaseParams>, BaseReturn>
: never
: never;
interface TypedGenericResolver4<BaseParams extends unknown[], BaseReturn>
extends Fn<[...BaseParams, BaseReturn]> {
on____: () => [BaseParams, BaseReturn];
on1___: (_: any) => [[unknown, unknown, unknown], unknown];
on_1__: (_: any) => [[unknown, unknown, unknown], unknown];
on__1_: (_: any) => [[unknown, unknown, unknown], unknown];
on___1: (_: any) => [[unknown, unknown, unknown], unknown];
on11__: (_: any) => [[unknown, unknown], unknown];
on1_1_: (_: any) => [[unknown, unknown], unknown];
on1__1: (_: any) => [[unknown, unknown], unknown];
on_11_: (_: any) => [[unknown, unknown], unknown];
on_1_1: (_: any) => [[unknown, unknown], unknown];
on__11: (_: any) => [[unknown, unknown], unknown];
on111_: (_: any) => [[unknown], unknown];
on11_1: (_: any) => [[unknown], unknown];
on1_11: (_: any) => [[unknown], unknown];
on_111: (_: any) => [[unknown], unknown];
on1111: (_: any) => [[], unknown];
on____r: (_: any) => BaseParams;
on1___r: (_: any) => [BaseParams[1], BaseParams[2], BaseParams[3]];
on_1__r: (_: any) => [BaseParams[0], BaseParams[2], BaseParams[3]];
on__1_r: (_: any) => [BaseParams[0], BaseParams[1], BaseParams[3]];
on___1r: (_: any) => [BaseParams[0], BaseParams[1], BaseParams[2]];
on11__r: (_: any) => [BaseParams[2], BaseParams[3]];
on1_1_r: (_: any) => [BaseParams[1], BaseParams[3]];
on1__1r: (_: any) => [BaseParams[1], BaseParams[2]];
on_11_r: (_: any) => [BaseParams[0], BaseParams[3]];
on_1_1r: (_: any) => [BaseParams[0], BaseParams[2]];
on__11r: (_: any) => [BaseParams[0], BaseParams[1]];
on111_r: (_: any) => [BaseParams[3]];
on11_1r: (_: any) => [BaseParams[2]];
on1_11r: (_: any) => [BaseParams[1]];
on_111r: (_: any) => [BaseParams[0]];
}
interface TypedGenericResolver3<BaseParams extends unknown[], BaseReturn>
extends Fn<[...BaseParams, BaseReturn]> {
on___: () => [BaseParams, BaseReturn];
on1__: (_: any) => [[unknown, unknown], unknown];
on_1_: (_: any) => [[unknown, unknown], unknown];
on__1: (_: any) => [[unknown, unknown], unknown];
on11_: (_: any) => [[unknown], unknown];
on1_1: (_: any) => [[unknown], unknown];
on_11: (_: any) => [[unknown], unknown];
on111: (_: any) => [[], unknown];
on___r: (_: any) => BaseParams;
on1__r: (_: any) => [BaseParams[1], BaseParams[2]];
on_1_r: (_: any) => [BaseParams[0], BaseParams[2]];
on__1r: (_: any) => [BaseParams[0], BaseParams[1]];
on11_r: (_: any) => [BaseParams[2]];
on1_1r: (_: any) => [BaseParams[1]];
on_11r: (_: any) => [BaseParams[0]];
}
interface TypedGenericResolver2<BaseParams extends unknown[], BaseReturn>
extends Fn<[...BaseParams, BaseReturn]> {
on__: () => [BaseParams, BaseReturn];
on1_: (_: any) => [[unknown], unknown];
on_1: (_: any) => [[unknown], unknown];
on11: (_: any) => [[], unknown];
on__r: (_: any) => BaseParams;
on1_r: (_: any) => [BaseParams[1]];
on_1r: (_: any) => [BaseParams[0]];
}
interface TypedGenericResolver1<BaseParams extends unknown[], BaseReturn>
extends Fn<[...BaseParams, BaseReturn]> {
on_: () => [BaseParams, BaseReturn];
on1: (_: any) => [[], unknown];
on_r: (_: any) => BaseParams;
}
/**
* Apply a {@link GenericResolver} by mask and arguments.
*
* Type safety is **not guaranteed**.
*/
export type ApplyGenericResolver<
F extends Fn,
Mask extends string,
Args extends readonly unknown[],
> =
F & { readonly Args: (_: Args) => void } extends {
readonly [P in `on${Mask}`]: (...args: never[]) => infer R;
} ?
R
: void;
type PartialApplyGenericResolverBy1<Resolver extends Fn, A1> =
Resolver extends Fn4 ? PartialApplyGenericResolver3by1<Resolver, A1>
: Resolver extends Fn3 ? PartialApplyGenericResolver2by1<Resolver, A1>
: never;
interface PartialApplyGenericResolver3by1<Resolver extends Fn, A1> extends GenericResolver<2> {
on__: () => ApplyGenericResolver<Resolver, "1__", [A1, Arg0<this>, Arg1<this>, never]>;
on1_: () => ApplyGenericResolver<Resolver, "11_", [A1, Arg0<this>, never, never]>;
on_1: () => ApplyGenericResolver<Resolver, "1_1", [A1, never, Arg1<this>, never]>;
on11: () => ApplyGenericResolver<Resolver, "111", [A1, Arg0<this>, Arg1<this>, never]>;
on__r: () => ApplyGenericResolver<Resolver, "1__r", [A1, never, never, Arg2<this>]>;
on1_r: () => ApplyGenericResolver<Resolver, "11_r", [A1, Arg0<this>, never, Arg2<this>]>;
on_1r: () => ApplyGenericResolver<Resolver, "1_1r", [A1, never, Arg1<this>, Arg2<this>]>;
}
interface PartialApplyGenericResolver3by2<Resolver extends Fn, A2> extends GenericResolver<2> {
on__: () => ApplyGenericResolver<Resolver, "_1_", [never, A2, never, never]>;
on1_: () => ApplyGenericResolver<Resolver, "11_", [Arg0<this>, A2, never, never]>;
on_1: () => ApplyGenericResolver<Resolver, "_11", [never, A2, Arg1<this>, never]>;
on11: () => ApplyGenericResolver<Resolver, "111", [Arg0<this>, A2, Arg1<this>, never]>;
on__r: () => ApplyGenericResolver<Resolver, "_1_r", [never, A2, never, Arg2<this>]>;
on1_r: () => ApplyGenericResolver<Resolver, "11_r", [Arg0<this>, A2, never, Arg2<this>]>;
on_1r: () => ApplyGenericResolver<Resolver, "_11r", [never, A2, Arg1<this>, Arg2<this>]>;
}
interface PartialApplyGenericResolver3by3<Resolver extends Fn, A3> extends GenericResolver<2> {
on__: () => ApplyGenericResolver<Resolver, "__1", [never, never, A3, never]>;
on1_: () => ApplyGenericResolver<Resolver, "1_1", [Arg0<this>, never, A3, never]>;
on_1: () => ApplyGenericResolver<Resolver, "_11", [never, Arg1<this>, A3, never]>;
on11: () => ApplyGenericResolver<Resolver, "111", [Arg0<this>, Arg1<this>, A3, never]>;
on__r: () => ApplyGenericResolver<Resolver, "__1r", [never, never, A3, Arg2<this>]>;
on1_r: () => ApplyGenericResolver<Resolver, "1_1r", [Arg0<this>, never, A3, Arg2<this>]>;
on_1r: () => ApplyGenericResolver<Resolver, "_11r", [never, Arg1<this>, A3, Arg2<this>]>;
}
interface PartialApplyGenericResolver3by12<Resolver extends Fn, A1, A2> extends GenericResolver<1> {
on_: () => ApplyGenericResolver<Resolver, "11_", [A1, A2, never, never]>;
on1: () => ApplyGenericResolver<Resolver, "111", [A1, A2, ...Args<this>]>;
on_r: () => ApplyGenericResolver<Resolver, "11_r", [A1, A2, never, Arg1<this>]>;
}
interface PartialApplyGenericResolver3by13<Resolver extends Fn, A1, A3> extends GenericResolver<1> {
on_: () => ApplyGenericResolver<Resolver, "1_1", [A1, ...Args<this>, A3]>;
on1: () => ApplyGenericResolver<Resolver, "111", [A1, ...Args<this>, A3]>;
on_r: () => ApplyGenericResolver<Resolver, "1_1r", [A1, never, A3, Arg1<this>]>;
}
interface PartialApplyGenericResolver3by23<Resolver extends Fn, A2, A3> extends GenericResolver<1> {
on_: () => ApplyGenericResolver<Resolver, "_11", [...Args<this>, A2, A3]>;
on1: () => ApplyGenericResolver<Resolver, "111", [...Args<this>, A2, A3]>;
on_r: () => ApplyGenericResolver<Resolver, "_11r", [never, A2, A3, Arg1<this>]>;
}
interface PartialApplyGenericResolver2by1<Resolver extends Fn, A1> extends GenericResolver<1> {
on_: () => ApplyGenericResolver<Resolver, "1_", [A1, ...Args<this>]>;
on1: () => ApplyGenericResolver<Resolver, "11", [A1, ...Args<this>]>;
on_r: () => ApplyGenericResolver<Resolver, "1_r", [A1, never, Arg1<this>]>;
}
interface PartialApplyGenericResolver2by2<Resolver extends Fn, A2> extends GenericResolver<1> {
on_: () => ApplyGenericResolver<Resolver, "_1", [...Args<this>, A2]>;
on1: () => ApplyGenericResolver<Resolver, "11", [...Args<this>, A2]>;
on_r: () => ApplyGenericResolver<Resolver, "_1r", [never, A2, Arg1<this>]>;
}
type PartialApplyGenericResolver<
Resolver extends Fn,
Mask,
AppliedArgs extends readonly unknown[],
> =
Mask extends "1__" ? PartialApplyGenericResolver3by1<Resolver, AppliedArgs[0]>
: Mask extends "_1_" ? PartialApplyGenericResolver3by2<Resolver, AppliedArgs[0]>
: Mask extends "__1" ? PartialApplyGenericResolver3by3<Resolver, AppliedArgs[0]>
: Mask extends "11_" ? PartialApplyGenericResolver3by12<Resolver, AppliedArgs[0], AppliedArgs[1]>
: Mask extends "1_1" ? PartialApplyGenericResolver3by13<Resolver, AppliedArgs[0], AppliedArgs[1]>
: Mask extends "_11" ? PartialApplyGenericResolver3by23<Resolver, AppliedArgs[0], AppliedArgs[1]>
: Mask extends "1_" ? PartialApplyGenericResolver2by1<Resolver, AppliedArgs[0]>
: Mask extends "_1" ? PartialApplyGenericResolver2by2<Resolver, AppliedArgs[0]>
: never;
/**
* Curry a {@link GenericResolver}.
*/
type CurryGenericResolver<Resolver extends Fn> =
Resolver extends Fn<[never, never, never, never, never]> ? CurryGenericResolver4<Resolver>
: Resolver extends Fn4 ? CurryGenericResolver3<Resolver>
: Resolver extends Fn3 ? CurryGenericResolver2<Resolver>
: Resolver extends Fn2 ? Resolver
: never;
interface CurryGenericResolver4<Resolver extends Fn<[never, never, never, never, never]>>
extends GenericResolver<1> {
on_: () => ApplyGenericResolver<Resolver, "____", [never, never, never, never, never]> extends (
readonly [readonly [infer A1, infer A2, infer A3, infer A4], infer R]
) ?
[[A1], Fn1<A2, Fn1<A3, Fn1<A4, R>>>]
: never;
on1: () => ApplyGenericResolver<
Resolver,
"1___",
[Arg0<this>, never, never, never, never]
> extends readonly [readonly [infer A2, infer A3, infer A4], infer R] ?
[[A2], Fn1<A3, Fn1<A4, R>>]
: never;
on_r: ([, r]: Args<this>) => typeof r extends Fn1<infer A, Fn1<infer B, Fn1<infer C, infer R>>> ?
[A, B, C, R] extends [never, never, never, never] ?
ApplyGenericResolver<Resolver, "____", [never, never, never, never, never]> extends (
readonly [readonly [infer A1, unknown, unknown, unknown], unknown]
) ?
[A1]
: never
: [A, B, C] extends [never, never, never] ?
ApplyGenericResolver<Resolver, "____r", [never, never, never, never, R]> extends (
readonly [infer A1, unknown, unknown, unknown]
) ?
[A1]
: never
: [A, B, R] extends [never, never, never] ?
ApplyGenericResolver<Resolver, "___1", [never, never, never, C, never]> extends (
readonly [readonly [infer A1, unknown, unknown, unknown], unknown]
) ?
[A1]
: never
: [A, C, R] extends [never, never, never] ?
ApplyGenericResolver<Resolver, "__1_", [never, never, B, never, never]> extends (
readonly [readonly [infer A1, unknown, unknown, unknown], unknown]
) ?
[A1]
: never
: [B, C, R] extends [never, never, never] ?
ApplyGenericResolver<Resolver, "_1__", [never, A, never, never, never]> extends (
readonly [readonly [infer A1, unknown, unknown, unknown], unknown]
) ?
[A1]
: never
: [A, B] extends [never, never] ?
ApplyGenericResolver<Resolver, "___1r", [never, never, never, C, R]> extends (
readonly [infer A1, unknown, unknown]
) ?
[A1]
: never
: [A, C] extends [never, never] ?
ApplyGenericResolver<Resolver, "__1_r", [never, never, B, never, R]> extends (
readonly [infer A1, unknown, unknown]
) ?
[A1]
: never
: [A, R] extends [never, never] ?
ApplyGenericResolver<Resolver, "__11", [never, never, B, C, never]> extends (
readonly [readonly [infer A1, unknown], unknown]
) ?
[A1]
: never
: [B, C] extends [never, never] ?
ApplyGenericResolver<Resolver, "_1__r", [never, A, never, never, R]> extends (
readonly [infer A1, unknown, unknown]
) ?
[A1]
: never
: [B, R] extends [never, never] ?
ApplyGenericResolver<Resolver, "_1_1", [never, A, never, C, never]> extends (
readonly [readonly [infer A1, unknown], unknown]
) ?
[A1]
: never
: [C, R] extends [never, never] ?
ApplyGenericResolver<Resolver, "_11_", [never, A, B, never, never]> extends (
readonly [readonly [infer A1, unknown], unknown]
) ?
[A1]
: never
: [A] extends [never] ?
ApplyGenericResolver<Resolver, "__11r", [never, never, B, C, R]> extends (
readonly [infer A1, unknown]
) ?
[A1]
: never
: [B] extends [never] ?
ApplyGenericResolver<Resolver, "_1_1r", [never, A, never, C, R]> extends (
readonly [infer A1, unknown]
) ?
[A1]
: never
: [C] extends [never] ?
ApplyGenericResolver<Resolver, "_11_r", [never, A, B, never, R]> extends (
readonly [infer A1, unknown]
) ?
[A1]
: never
: [R] extends [never] ?
ApplyGenericResolver<Resolver, "_111", [never, A, B, C, never]> extends (
readonly [readonly [infer A1], unknown]
) ?
[A1]
: never
: ApplyGenericResolver<Resolver, "_111r", [never, A, B, C, R]> extends readonly [infer A1] ?
[A1]
: never
: never;
}
interface CurryGenericResolver3<Resolver extends Fn4> extends GenericResolver<1> {
on_: () => ApplyGenericResolver<Resolver, "___", [never, never, never, never]> extends (
readonly [readonly [infer A1, infer A2, infer A3], infer R]
) ?
[[A1], Fn1<A2, Fn1<A3, R>>]
: never;
on1: () => ApplyGenericResolver<Resolver, "1__", [Arg0<this>, never, never, never]> extends (
readonly [readonly [infer A2, infer A3], infer R]
) ?
[[A2], Fn1<A3, R>]
: never;
on_r: ([, r]: Args<this>) => typeof r extends Fn1<infer A, Fn1<infer B, infer R>> ?
[A, B, R] extends [never, never, never] ?
ApplyGenericResolver<Resolver, "___", [never, never, never, never]> extends (
readonly [readonly [infer A1, unknown, unknown], unknown]
) ?
[A1]
: never
: [A, B] extends [never, never] ?
ApplyGenericResolver<Resolver, "___r", [never, never, never, R]> extends (
readonly [infer A1, unknown, unknown]
) ?
[A1]
: never
: [A, R] extends [never, never] ?
ApplyGenericResolver<Resolver, "__1", [never, never, B, never]> extends (
readonly [readonly [infer A1, unknown], unknown]
) ?
[A1]
: never
: [B, R] extends [never, never] ?
ApplyGenericResolver<Resolver, "_1_", [never, A, never, never]> extends (
readonly [readonly [infer A1, unknown], unknown]
) ?
[A1]
: never
: [A] extends [never] ?
ApplyGenericResolver<Resolver, "__1r", [never, never, B, R]> extends (
readonly [infer A1, unknown]
) ?
[A1]
: never
: [B] extends [never] ?
ApplyGenericResolver<Resolver, "_1_r", [never, A, never, R]> extends (
readonly [infer A1, unknown]
) ?
[A1]
: never
: [R] extends [never] ?
ApplyGenericResolver<Resolver, "_11", [never, A, B, never]> extends (
readonly [readonly [infer A1], unknown]
) ?
[A1]
: never
: ApplyGenericResolver<Resolver, "_11r", [never, A, B, R]> extends readonly [infer A1] ? [A1]
: never
: never;
}
interface CurryGenericResolver2<Resolver extends Fn3> extends GenericResolver<1> {
on_: () => ApplyGenericResolver<Resolver, "__", [never, never, never]> extends (
readonly [readonly [infer A1, infer A2], infer R]
) ?
[[A1], Fn1<A2, R> & { readonly GenericResolver: PartialApplyGenericResolver2by1<Resolver, A1> }]
: never;
on1: ([a1]: Args<this>) => ApplyGenericResolver<
Resolver,
"1_",
[typeof a1, never, never]
> extends readonly [readonly [infer A2], infer R] ?
[
[],
Fn1<A2, R> & {
readonly GenericResolver: PartialApplyGenericResolver2by1<Resolver, typeof a1>;
},
]
: never;
on_r: ([, r]: Args<this>) => typeof r extends Fn1<infer A, infer R> ?
[A] extends [never] ?
ApplyGenericResolver<Resolver, "__r", [never, never, R]> extends (
readonly [infer A1, unknown]
) ?
[A1]
: never
: [R] extends [never] ?
ApplyGenericResolver<Resolver, "_1", [never, A, never]> extends (
readonly [readonly [infer A1], unknown]
) ?
[A1]
: never
: ApplyGenericResolver<Resolver, "_1r", [never, Param0W<typeof r>, ReturnW<typeof r>]>
: never;
}
type ResolveGenericSignature<
Resolver extends Fn,
Mask extends string,
PinnedArgs extends readonly unknown[],
> = ApplyGenericResolver<Resolver, Mask, [...BuildPartialArgs<Mask, PinnedArgs>, never]>;
/**
* A generic type level function.
*
* @example
* ```typescript
* import type { Args, Ask, Broaden, Flow, GenericFn, GenericResolver, PartialApply, Sig } from "rivo";
*
* // Say you want to define a type level function `Append` with signature
* // `<T>(x: T, xs: T[]) => T[]`.
*
* // Define a resolver to represent the signature first
* interface Resolver extends GenericResolver<[unknown, unknown[]], unknown[]> {
* // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
* // The base signature when no arguments are applied (`(x: unknown, xs: unknown[]) => unknown[]`)
*
* // β How the resolver refines the function signature when the first argument is applied
* // Here, `1_` means the first argument is applied (the corresponding char is `1`),
* // and the second argument is not applied (the corresponding char is `_`).
* // The rest will follow the same pattern, e.g., `on_1` means when the first argument is not
* // applied and the second argument is applied, `on11` means when both arguments are applied.
* on1_: ([x]: Args<this>) => [[Broaden<typeof x>[]], Broaden<typeof x>[]];
* // A `GenericResolver` can be seen as sort of type-level function, where it takes a tuple of
* // already known parameter types and return type, and refines the signature based on them.
* // Here, for `on1_`, we know the first parameter type, so the input tuple would be
* // `[<type_of_x>, never, never]` (because the second parameter type and the return type are not
* // known yet).
* // Letβs think about how can we refine the signature based on the input tuple, and in this
* // case, the only known parameter type is `<type_of_x>`. Take a back look at the expected
* // signature `<T>(x: T, xs: T[]) => T[]`, since we already know the type of `x`, we can infer
* // the type of `T`, so the type of `xs` would be `<type_of_x>[]`, and the return type would be
* // `<type_of_x>[]` as well. We should write them in the form of
* // `[[...<rest_parameter_types>], <return_type>]`, so we get `[[(typeof x)[]], (typeof x)[]]`
* // here β But actually weβll get precise types like `42` instead of `number` sometimes, and in
* // such case the inferred signature would be `(x: 42, xs: 42[]) => 42[]` if we just use
* // `[[(typeof x)[]], (typeof x)[]]`, so here we use `Broaden` to get a more general type. The
* // use of `Broaden` is not a must, and sometimes you may actually want a precise type, in such
* // case you should just use `typeof x` directly.
*
* // β Things are similar for the rest of the methods, take a look and try to understand them.
* on_1: ([, xs]: Args<this>) => [[Broaden<(typeof xs)[number]>], Broaden<(typeof xs)[number]>[]];
* // ^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
* // β Inferred type of `x` Inferred return type
* // Input tuple: `[never, <type_of_xs>, never]`
*
* // β When both parameter types are known, we left the `[...<rest_parameter_types>]` tuple empty
* // (i.e. `[]`), and only need to return the inferred return type.
* on11: ([x, xs]: Args<this>) => [[], (typeof x | (typeof xs)[number])[]];
*
* // β Things become a little special when we want to back infer the parameter types from the
* // return type β if you wonder why we need this, think about a function that requires another
* // function that returns a specific type as a parameter, and in such case we can refine the
* // parameter types based on the return type of the function.
* // We use a `r` postfix here to indicate the return type is known, and the `__` in `__r`
* // means both parameter types are not known.
* // We do not use the form `[[...<rest_parameter_types>], <return_type>]` here, because we
* // already know the return type, so we just need to return the inferred parameter types (i.e.
* // `[...<rest_parameter_types>]`).
* on__r: ([, , r]: Args<this>) => [(typeof r)[number], typeof r];
* // You can see here we choose not to use `Broaden`, because usually the known return type is
* // not a precise type, so it is not necessary to use `Broaden` here.
*
* // β Define other back inference methods when some parameter types are known.
* on1_r: ([x, , r]: Args<this>) => [typeof r];
*
* on_1r: ([, xs, r]: Args<this>) => [(typeof r)[number]];
*
* // `on11r` is apparently not needed, because since we already know all parameter types and the
* // return type, there is no need to back infer any parameter types.
* // on11r: Not needed
* }
*
* // Then define the type level function with its `GenericResolver`
* interface AppendFn extends GenericFn<Resolver> {
* def: ([x, xs]: Args<this>) => [...typeof xs, typeof x];
* }
*
* type S1 = Sig<AppendFn>;
* // ^?: (x: unknown, xs: unknown[]) => unknown[]
* // β `on1_` is used here to refine the signature
* type S2 = Sig<PartialApply<AppendFn, [42]>>;
* // ^?: (ns: number[]) => number[]
* // β `on_1` is used here to refine the signature
* type S3 = Sig<PartialApply<AppendFn, [["foo", "bar"]], "_1">>;
* // ^?: (s: string) => string[]
*
* type AppendWithFn<T> = PartialApply<AppendFn, [T]>;
* // β `on11` is used here to refine the signature
* type S4 = Sig<Flow<Ask<number[]>, AppendWithFn<42>>>;
* // ^?: (ns: number[]) => number[]
* // β `on1_` is used here to give the type error (the inferred signature of `AppendWithFn<"foo">` is
* // `(ss: string[]) => string[]`, but we expect a function that takes `number[]` as the parameter)
* type Wrong = Flow<Ask<number[]>, AppendWithFn<"foo">>;
* // ~~~~~~~~~~~~~~~~~~~
* // ... Type 'number' is not assignable to type 'string'.
* ```
*
* @see {@link GenericResolver}
*/
export type GenericFn<ResolverOrParams extends Fn | unknown[] = never, Return = unknown> =
[ResolverOrParams] extends [infer Params extends unknown[]] ?
Fn<Params, Return> & {
readonly GenericResolver: Fn<
[..._DeReadonly<Repeat<Params["length"], never>>, never],
unknown
>;
}
: [ResolverOrParams] extends [infer Resolver extends Fn] ?
ResolveGenericSignature<
Resolver,
RepeatString<Tail<Params<Resolver>>["length"], "_">,
[]
> extends [infer Args extends unknown[], infer Return] ?
Fn<_DeReadonly<Args>, Return> & { readonly GenericResolver: Resolver }
: never
: never;
/**
* Specialize a generic type level function with the given arguments.
*/
export interface Specialize<
F extends Fn & { readonly GenericResolver: Fn },
PinnedParams extends Mask extends "default" ? LegalPinnedArgsDefault<F>
: LegalPinnedArgs<F, Mask>,
Mask extends string = "default",
> extends Fn<
ResolveGenericSignature<
F["GenericResolver"],
Mask extends "default" ? MaskDefault<F, PinnedParams> : Mask,
PinnedParams
> extends readonly [infer UnpinnedParams extends readonly unknown[], unknown] ?
_DeReadonly<
ApplyArgs<
Mask extends "default" ? MaskDefault<F, PinnedParams> : Mask,
PinnedParams,
UnpinnedParams
>
>
: never,
ResolveGenericSignature<
F["GenericResolver"],
Mask extends "default" ? MaskDefault<F, PinnedParams> : Mask,
PinnedParams
> extends readonly [readonly unknown[], infer R] ?
R
: never
> {
def: () => ApplyW<F, Args<this>>;
}
/**
* Call a type level function with the given argument list.
*
* Type safety is **guaranteed**.
*
* @example
* ```typescript
* type R1 = Call<Num.ToStr, [42]>;
* // ^?: "42"
* type R2 = Call<Str.Prepend, ["foo", "bar"]>;
* // ^?: "foobar"
* ```
*/
export type Apply<F extends Fn, Args extends Params<F>> = ApplyW<F, Args>;
/**
* The **unsafe** version of {@link Apply} (i.e. no type checking with `F` and `Args`).
*/
export type ApplyW<F, Args> =
F & { readonly Args: (_: Args) => void } extends { readonly def: (...args: never[]) => infer R } ?
R
: never;
/**
* Apply a type level function with variadic arguments (up to 4 arguments).
*
* Type safety is **guaranteed**.
*
* @example
* ```typescript
* type R1 = Call<Num.ToStr, 42>;
* // ^?: "42"
* type R2 = Call<Str.Prepend, "foo", "bar">;
* // ^?: "foobar"
* ```
*/
export type Call<
F extends Fn0 | Fn1 | Fn2 | Fn3 | Fn4,
A extends ParamsLength<F> extends 1 | 2 | 3 | 4 ? Params<F>[0] : never = never,
B extends ParamsLength<F> extends 2 | 3 | 4 ? Params<F>[1] : never = never,
C extends ParamsLength<F> extends 3 | 4 ? Params<F>[2] : never = never,
D extends ParamsLength<F> extends 4 ? Params<F>[3] : never = never,
> =
F & { readonly Args: (_: [A, B, C, D]) => void } extends (
{ readonly def: (...args: never[]) => infer R }
) ?
R
: never;
/**
* Apply a type level function with variadic arguments (up to 4 arguments).
*
* Alias of {@link Call}.
*
* Type safety is **guaranteed**.
*
* @example
* ```typescript
* type R1 = $<Num.ToStr, 42>;
* // ^?: "42"
* type R2 = $<Str.Prepend, "foo", "bar">;
* // ^?: "foobar"
* ```
*/
export type $<
F extends Fn0 | Fn1 | Fn2 | Fn3 | Fn4,
A extends ParamsLength<F> extends 1 | 2 | 3 | 4 ? Params<F>[0] : never = never,
B extends ParamsLength<F> extends 2 | 3 | 4 ? Params<F>[1] : never = never,
C extends ParamsLength<F> extends 3 | 4 ? Params<F>[2] : never = never,
D extends ParamsLength<F> extends 4 ? Params<F>[3] : never = never,
> = Call<F, A, B, C, D>;
export type Call0<F extends Fn0> = Call0W<F>;
export type Call0W<F> = F extends { readonly def: (...args: never[]) => infer R } ? R : never;
export type Call1<F extends Fn1, A extends Param0<F>> = Call1W<F, A>;
export type Call1W<F, A> =
F & { readonly Args: (_: [A]) => void } extends { readonly def: (...args: never[]) => infer R } ?
R
: never;
export type Call2<F extends Fn2, A extends Param0<F>, B extends Param1<F>> = Call2W<F, A, B>;
export type Call2W<F, A, B> =
F & { readonly Args: (_: [A, B]) => void } extends (
{ readonly def: (...args: never[]) => infer R }
) ?
R
: never;
/**
* Keep only the arguments that are not masked by `1` in `Mask`.
*
* `Params` and `Mask` should be the same length.
*
* @example
* ```typescript
* type R = MaskPinnedArgs<[string, number, boolean], "1_1">;
* // ^?: [number]
* ```
*/
type MaskPinnedArgs<Params, Mask> =
Params extends readonly [infer ParamsHead, ...infer ParamsTail] ?
Mask extends `${infer Mask}${infer RestMask}` ?
Mask extends "1" ?
MaskPinnedArgs<ParamsTail, RestMask>
: [ParamsHead, ...MaskPinnedArgs<ParamsTail, RestMask>]
: Params
: [];
/**
* Replace `1` in `Mask` with the corresponding value in `PinnedArgs` and `_` in `Mask` with the
* the corresponding value in `AppliedArgs` (i.e. apply the arguments).
*
* The number of `1` and `_` should match the length of `PinnedArgs` and `AppliedArgs` respectively.
*
* @example
* ```typescript
* type R = ApplyArgs<"1__1", [true, "foo"], [12, "bar"]>;
* // ^?: [true, 12, "bar", "foo"]
* ```
*/
type ApplyArgs<Mask, PinnedArgs, AppliedArgs> =
Mask extends `${infer Mask}${infer RestMask}` ?
Mask extends "1" ?
PinnedArgs extends readonly [infer PinnedArgsHead, ...infer PinnedArgsTail] ?
[PinnedArgsHead, ...ApplyArgs<RestMask, PinnedArgsTail, AppliedArgs>]
: never
: AppliedArgs extends readonly [infer AppliedArgsHead, ...infer AppliedArgsTail] ?
[AppliedArgsHead, ...ApplyArgs<RestMask, PinnedArgs, AppliedArgsTail>]
: never
: [];
/**
* Replace each `1` in `Mask` with the corresponding value in `PinnedArgs` and `_` with `never`.
*
* @example
* ```typescript
* type R = BuildPartialArgs<"1__1", [true, "foo"]>;
* // ^?: [true, never, never, "foo"]
* ```
*/
type BuildPartialArgs<Mask extends string, PinnedArgs extends readonly unknown[]> =
Mask extends `${infer Mask}${infer RestMask}` ?
Mask extends "1" ?
PinnedArgs extends readonly [infer AppliedArgsHead, ...infer AppliedArgsTail] ?
[AppliedArgsHead, ...BuildPartialArgs<RestMask, AppliedArgsTail>]
: never
: [never, ...BuildPartialArgs<RestMask, PinnedArgs>]
: [];
interface PartialApplyNormal<
F extends Fn,
Mask extends string,
PinnedArgs extends readonly unknown[],
> extends Fn<MaskPinnedArgs<Params<F>, Mask>, Return<F>> {
readonly def: () => ApplyW<F, ApplyArgs<Mask, PinnedArgs, Args<this>>>;
}
interface PartialApplyGeneric<
F extends Fn & { readonly GenericResolver: Fn },
Mask extends string,
PinnedArgs extends readonly unknown[],
> extends Fn<
ResolveGenericSignature<F["GenericResolver"], Mask, PinnedArgs> extends (
[infer Args extends readonly unknown[], unknown]
) ?
_DeReadonly<Args>
: never,
ResolveGenericSignature<F["GenericResolver"], Mask, PinnedArgs> extends (
[readonly unknown[], infer Return]
) ?
Return
: never
> {
readonly GenericResolver: PartialApplyGenericResolver<F["GenericResolver"], Mask, PinnedArgs>;
readonly def: () => ApplyW<F, ApplyArgs<Mask, PinnedArgs, Args<this>>>;
}
/**
* Partially apply a type level function with the given argument list.
*
* Type safety is **not guaranteed**.
*
* @example
* ```typescript
* type F1 = PartialApplyW<Str.Concat, ["foo"]>;
* // ^?: Fn<[string], string>
* type R1 = $<F1, "bar">;
* // ^?: "foobar"
* type F2 = PartialApplyW<Str.Concat, ["bar"], "_1">;
* // ^?: Fn<[string], string>
* type R2 = $<F2, "foo">;
* // ^?: "foobar"
* ```
*/
export type PartialApplyW<
F extends Fn,
PinnedArgs extends readonly unknown[],
Mask extends string = "default",
> =
F extends { readonly GenericResolver: Fn } ?
PartialApplyGeneric<F, Mask extends "default" ? MaskDefault<F, PinnedArgs> : Mask, PinnedArgs>
: PartialApplyNormal<F, Mask extends "default" ? MaskDefault<F, PinnedArgs> : Mask, PinnedArgs>;
/**
* Partially apply a type level function with the given argument list.
*
* Type safety is **guaranteed**.
*
* @example
* ```typescript
* type F1 = PartialApply<Str.Prepend, ["foo"]>;
* // ^?: Fn<[string], string>
* type R1 = $<F1, "bar">;
* // ^?: "foobar"
* type F2 = PartialApply<Str.Prepend, ["bar"], "_1">;
* // ^?: Fn<[string], string>
* type R2 = $<F2, "foo">;
* // ^?: "foobar"
* ```
*/
export type PartialApply<
F extends Fn,
PinnedArgs extends Mask extends "default" ? LegalPinnedArgsDefault<F> : LegalPinnedArgs<F, Mask>,
Mask extends string = "default",
> = PartialApplyW<F, PinnedArgs, Mask>;
type MaskDefault<F extends Fn, PinnedArgs extends readonly unknown[]> = _MaskDefault<
Params<F>,
PinnedArgs
>;
type _MaskDefault<Params extends readonly unknown[], PinnedArgs extends readonly unknown[]> =
Params extends readonly [unknown, ...infer ParamsTail] ?
PinnedArgs extends readonly [unknown, ...infer PinnedArgsTail] ?
`1${_MaskDefault<ParamsTail, PinnedArgsTail>}`
: `_${_MaskDefault<ParamsTail, PinnedArgs>}`
: "";
type LegalPinnedArgsDefault<F extends Fn> = _LegalPinnedArgsDefault<Params<F>>;
type _LegalPinnedArgsDefault<Args extends readonly unknown[]> =
Args extends readonly [...infer Init, unknown] ? Init | Args : readonly [];
type LegalPinnedArgs<F extends Fn, RestMask extends string> = _LegalPinnedArgs<Params<F>, RestMask>;
type _LegalPinnedArgs<RestParams extends readonly unknown[], RestMask extends string> =
RestParams extends readonly [infer Head, ...infer Tail] ?
RestMask extends `${infer Mask}${infer RestMask}` ?
Mask extends "1" ?
[Head, ..._LegalPinnedArgs<Tail, RestMask>]
: _LegalPinnedArgs<Tail, RestMask>
: never
: readonly [];
type Tail<TS> = TS extends readonly [unknown, ...infer Tail] ? Tail : [];
type _CurryReturn<Args extends readonly unknown[], Return> =
Args["length"] extends 0 ? Return
: Fn1<Args[0], _CurryReturn<Args extends readonly [unknown, ...infer Tail] ? Tail : [], Return>>;
/**
* Curry a type level function.
*
* Type safety is **guaranteed**.
*
* @example
* ```typescript
* type F = Curry<Str.Concat>;
* // ^?: Fn<[string], Fn<[string], string>>
* type R = $<$<F, "foo">, "bar">;
* // ^?: "foobar"
* ```
*/
export type Curry<F extends Fn> =
F extends { readonly GenericResolver: Fn } ? CurryGeneric<F> : CurryNormal<F>;
interface CurryNormal<F extends Fn>
extends Fn<
ParamsLength<F> extends 0 ? [] : [Param0<F>],
_CurryReturn<Tail<Params<F>>, Return<F>>
> {
readonly def: () => ParamsLength<F> extends 0 ? ApplyW<F, []>
: ParamsLength<F> extends 1 ? ApplyW<F, [Arg0<this>]>
: Curry<PartialApplyW<F, [Arg0<this>]>>;
}
interface CurryGeneric<F extends Fn & { readonly GenericResolver: Fn }>
extends Fn<
ParamsLength<F> extends 0 ? [] : [Param0<F>],
_CurryReturn<Tail<Params<F>>, Return<F>> & {
readonly GenericResolver: PartialApplyGenericResolverBy1<F["GenericResolver"], Param0W<F>>;
}
> {
readonly GenericResolver: CurryGenericResolver<F["GenericResolver"]>;
readonly def: () => ParamsLength<F> extends 0 ? ApplyW<F, []>
: ParamsLength<F> extends 1 ? ApplyW<F, [Arg0<this>]>
: Curry<PartialApplyW<F, [Arg0<this>]>>;
}
/**
* Flip the order of the first two arguments of a type level function.
*
* Sig1: `<T, U, V>(f: (x: T, y: U) => V) => (y: U, x: T) => V`
*
* Sig2: `<T, U, V>(f: (x: T) => (y: U) => V) => (y: U) => (x: T) => V`
*/
export type Flip<F extends Fn2 | Fn1<never, Fn1>> =
F extends Fn2 ?
F extends { readonly GenericResolver: Fn } ?
Flip2Generic<F>
: Flip2Normal<F>
: F extends { readonly GenericResolver: Fn } ?
Return<F> extends { readonly GenericResolver: Fn } ?
F extends (
Fn1<never, Fn1<never, unknown> & { readonly GenericResolver: Fn }> & {
readonly GenericResolver: Fn;
}
) ?
Flip1GenericGeneric<F>
: never
: F extends Fn1<never, Fn1<never, unknown>> & { readonly GenericResolver: Fn } ?
Flip1GenericNormal<F>
: never
: Return<F> extends { readonly GenericResolver: Fn } ?
F extends Fn1<never, Fn1<never, unknown> & { readonly GenericResolver: Fn }> ?
Flip1NormalGeneric<F>
: never
: F extends Fn1<never, Fn1<never, unknown> & { readonly GenericResolver: Fn }> ?
Flip1NormalNormal<F>
: never;
interface Flip2Normal<F extends Fn2> extends Fn<[Param1<F>, Param0<F>], Return<F>> {
readonly def: () => ApplyW<F, [Arg1<this>, Arg0<this>]>;
}
interface Flip2Generic<F extends Fn2 & { readonly GenericResolver: Fn }>
extends GenericFn<[Param1<F>, Param0<F>], Return<F>> {
readonly GenericResolver: _Flip2GenericResolver<F["GenericResolver"]>;
readonly def: () => ApplyW<F, [Arg1<this>, Arg0<this>]>;
}
interface _Flip2GenericResolver<Resolver extends Fn> extends GenericResolver<2> {
on__: () => ApplyGenericResolver<Resolver, "__", [never, never, never]>;
on1_: () => ApplyGenericResolver<Resolver, "_1", [never, Arg0<this>, never]>;
on_1: () => ApplyGenericResolver<Resolver, "1_", [Arg1<this>, never, never]>;
on11: () => ApplyGenericResolver<Resolver, "11", [Arg1<this>, Arg0<this>, never]>;
}
interface Flip1NormalNormal<F extends Fn1<never, Fn1>>
extends Fn<[Param0<Return<F>>], Fn1<Param0<F>, Return<Return<F>>>> {
readonly def: () => _Flip1NormalNormal<F, Arg0<this>>;
}
interface _Flip1NormalNormal<F extends Fn1<never, Fn1>, A>
extends Fn<[Param0<F>], Return<Return<F>>> {
readonly def: () => ApplyW<ApplyW<F, Arg0<this>>, A>;
}
interface Flip1NormalGeneric<F extends Fn1<never, Fn1 & { readonly GenericResolver: Fn }>>
extends GenericFn<[Param0<Return<F>>], Fn1<Param0<F>, Return<Return<F>>>> {
readonly GenericResolver: _Flip1NormalGenericResolver<F>;
readonly def: () => _Flip1NormalGeneric<F, Arg0<this>>;
}
interface _Flip1NormalGenericResolver<F extends Fn1<never, Fn1 & { readonly GenericResolver: Fn }>>
extends GenericResolver<[Param0<Return<F>>], Fn1<Param0<F>, Return<Return<F>>>> {
on1: () => [[], ApplyGenericResolver<Return<F>["GenericResolver"], "1", [Arg0<this>, never]>];
}
interface _Flip1NormalGeneric<F extends Fn1<never, Fn1 & { readonly GenericResolver: Fn }>, A>
extends Fn<[Param0<F>], GenericReturn1W<Return<F>, A>> {
readonly def: () => ApplyW<ApplyW<F, Arg0<this>>, A>;
}
interface Flip1GenericNormal<F extends Fn1<never, Fn1> & { readonly GenericResolver: Fn }>
extends Fn<[Param0<Return<F>>], Fn1<Param0<F>, Return<Return<F>>>> {
readonly def: () => _Flip1GenericNormal<F, Arg0<this>>;
}
interface _Flip1GenericNormal<F extends Fn1<never, Fn1> & { readonly GenericResolver: Fn }, A>
extends GenericFn<[Param0<F>], Return<GenericReturn1W<F, A>>> {
readonly GenericResolver: _Flip1GenericNormalResolver<F>;
readonly def: () => ApplyW<ApplyW<F, Arg0<this>>, A>;
}
interface _Flip1GenericNormalResolver<F extends Fn1<never, Fn1> & { readonly GenericResolver: Fn }>
extends GenericResolver<[Param0<F>], Return<Return<F>>> {
on1: () => [[], ApplyGenericResolver<F["GenericResolver"], "1", [Arg0<this>, never]>];
}
interface Flip1GenericGeneric<
F extends Fn1<never, Fn1 & { readonly GenericResolver: Fn }> & { readonly GenericResolver: Fn },
> extends GenericFn<[Param0<Return<F>>], Fn1<Param0<F>, Return<Return<F>>>> {
readonly GenericResolver: _Flip1GenericGenericResolverOuter<F>;
readonly def: () => _Flip1GenericGeneric<F, Arg0<this>>;
}
interface _Flip1GenericGenericResolverOuter<
F extends Fn1<never, Fn1 & { readonly GenericResolver: Fn }> & { readonly GenericResolver: Fn },
> extends GenericResolver<[Param0<Return<F>>], Fn1<Param0<F>, Return<Return<F>>>> {
on1: () => [
[],
FnW<
ApplyGenericResolver<F["GenericResolver"], "_r", [never, Fn1<Arg0<this>, never>]>,
GenericReturn1W<Return<F>, Arg0<this>>
>,
];
}
interface _Flip1GenericGeneric<
F extends Fn1<never, Fn1 & { readonly GenericResolver: Fn }> & { readonly GenericResolver: Fn },
A,
> extends GenericFn<[Param0<F>], GenericReturn1W<Return<F>, A>> {
readonly GenericResolver: _Flip1GenericGenericResolverInner<F>;
readonly def: () => ApplyW<ApplyW<F, Arg0<this>>, A>;
}
interface _Flip1GenericGenericResolverInner<
F extends Fn1<never, Fn1 & { readonly GenericResolver: Fn }> & { readonly GenericResolver: Fn },
> extends GenericResolver<[Param0<F>], Return<Return<F>>> {
on1: () => [[], ApplyGenericResolver<F["GenericResolver"], "1", [Arg0<this>, never]>];
}
/**
* A type level function that always returns the same value.
*
* @example
* ```typescript
* type Always42 = Always<42>;
* type S = Sig<Always42>;
* // ^?: () => 42
* type R = $<Always42>;
* // ^?: 42
* ```
*/
export interface Always<T> extends Fn<[], T> {
def: () => T;
}
interface ComposeNormal<B extends Fn1<Return<A>>, A extends Fn1>
extends Fn1<Param0<A>, GenericReturn1W<B, Return<A>>> {
readonly def: () => Call1W<B, Call1<A, Arg0<this>>>;
}
interface _CombineGenericResolver1<Resolver1 extends Fn2, Resolver2 extends Fn2>
extends GenericResolver<1> {
on_: () => [
[
ApplyGenericResolver<Resolver1, "_", [Arg0<this>, never]> extends (
[readonly [infer P], unknown]
) ?
P
: never,
],
ApplyGenericResolver<Resolver2, "_", [Arg0<this>, never]> extends (
[readonly [unknown], infer R]
) ?
R
: never,
];
on1: () => ApplyGenericResolver<Resolver1, "1", [Arg0<this>, never]> extends (
[readonly [], infer R]
) ?
ApplyGenericResolver<Resolver2, "_", [R, never]>
: never;
}
interface ComposeGeneric<
B extends Fn1<Return<A>> & { readonly GenericResolver: Fn2 },
A extends Fn1 & { readonly GenericResolver: Fn2 },
> extends Fn1<Param0<A>, GenericReturn1W<B, Return<A>>> {
readonly GenericResolver: _CombineGenericResolver1<A["GenericResolver"], B["GenericResolver"]>;
readonly def: () => Call1W<B, Call1<A, Arg0<this>>>;
}
/**
* Compose two