rivo
Version:
🤖 The ultimate library you need for composable type-level programming in TypeScript, powered by HKT.
97 lines (86 loc) • 3.05 kB
TypeScript
import type { Call1W, Fn1, Return } from "../HKT";
import type { ValueOf } from "../Obj/ValueOf";
import type { Eq, Lazied, Lazied$Get } from "../helpers";
export type HKT = Lazied$Get<HKTL>;
/**
* {@link Lazied} version of {@link HKT}.
*/
export type HKTL = Lazied<Return<HKTRegistry[keyof HKTRegistry][0]>>;
/**
* Registry of HKT builders and extractors.
*
* Only HKT with **1** type parameter is supported.
*
* GADT is _not_ supported, i.e., the type builder must accept any type as its type parameter
* (should match `Fn1<unknown, unknown>`, not something like `Fn1<string, unknown>`).
*/
export interface HKTRegistry {}
/**
* Helper type for registering {@link HKT} builders and extractors.
*/
export type RegisterHKT<
Builder extends Fn1<unknown, unknown>,
Extractor extends Fn1<Return<Builder>, unknown>,
> = [Builder, Extractor];
/**
* Build an {@link HKT} from a type parameter.
*/
export type Kind<H extends HKT, A> =
HKT$GetBuilder<H> & { readonly Args: (_: [A]) => void } extends (
{ readonly def: (...args: never[]) => infer R }
) ?
R
: never;
/**
* Get the matching entry of {@link HKT} for `H`.
* @private
*/
type _HKT$GetMatch<H extends HKT> = ValueOf<{
[P in keyof HKTRegistry as H extends Return<HKTRegistry[P][0]> ? P : never]: HKTRegistry[P];
}>;
/**
* Get the builder of `H` from {@link HKTRegistry}.
*/
export type HKT$GetBuilder<H extends HKT> =
_HKT$GetMatch<H> extends [infer Builder extends Fn1<unknown, unknown>, unknown] ? Builder : never;
/**
* The **unsafe** version of {@link HKT$GetBuilder} (i.e. no type checking with `H`).
*/
export type HKT$GetBuilderW<H> = H extends HKT ? HKT$GetBuilder<H> : never;
/**
* Get the extractor of `H` from {@link HKTRegistry}.
*/
export type HKT$GetExtractor<H extends HKT> =
_HKT$GetMatch<H> extends [unknown, infer Extractor extends Fn1] ? Extractor : never;
/**
* The **unsafe** version of {@link HKT$GetExtractor} (i.e. no type checking with `H`).
*/
export type HKT$GetExtractorW<H> = H extends HKT ? HKT$GetExtractor<H> : never;
/**
* Extract the type parameter of `H`.
*/
export type HKT$Extract<H extends HKT> = Call1W<HKT$GetExtractor<H>, H>;
/**
* The **unsafe** version of {@link HKT$Extract} (i.e. no type checking with `H`).
*/
export type HKT$ExtractW<H> = H extends HKT ? HKT$Extract<H> : never;
/**
* Mutate the type parameter of `H`.
*/
export type HKT$Mutate<H extends HKT, T> = Call1W<HKT$GetBuilder<H>, T>;
/**
* The **unsafe** version of {@link HKT$Mutate} (i.e. no type checking with `H`).
*/
export type HKT$MutateW<H, T> = H extends HKT ? HKT$Mutate<H, T> : never;
/**
* Get the construct of `H` from {@link HKTRegistry}.
*/
export type HKT$GetConstruct<H extends HKT> =
Eq<H, HKT> extends true ? H
: _HKT$GetMatch<H> extends [infer Builder extends Fn1<unknown, unknown>, unknown] ?
Return<Builder>
: never;
/**
* The **unsafe** version of {@link HKT$GetConstruct} (i.e. no type checking with `H`).
*/
export type HKT$GetConstructW<H> = H extends HKT ? HKT$GetConstruct<H> : never;