UNPKG

rivo

Version:

🤖 The ultimate library you need for composable type-level programming in TypeScript, powered by HKT.

97 lines (86 loc) • 3.05 kB
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;