import { ContravariantParam, CovariantParam, InvariantParam, Param } from './variance'; /** * Higher Kinded Type (HKT) is a type constructor of a type constructor * @see https://en.wikipedia.org/wiki/Kind_(type_theory) * Here we use Kind is a way to encode a type constructor with variance * Using Kind we can declare HKTs like typeclasses */ export interface Kind { signature: params; rawArgs: unknown; arity: params['length']; arg0: params[0]['value']; arg1: params[1]['value']; arg2: params[2]['value']; arg3: params[3]['value']; arg4: params[4]['value']; arg5: params[5]['value']; arg6: params[6]['value']; arg7: params[7]['value']; arg8: params[8]['value']; arg9: params[9]['value']; arg10: params[10]['value']; arg11: params[11]['value']; arg12: params[12]['value']; arg13: params[13]['value']; arg14: params[14]['value']; arg15: params[15]['value']; } export interface TypeConstructor extends Kind { return: any; } export declare namespace Kind { export type nullary = Kind<[]>; export type unary = Kind<[InvariantParam]>; export type binary = Kind<[InvariantParam, CovariantParam]>; export type ternary = Kind<[InvariantParam, CovariantParam, CovariantParam]>; export type quaternary = Kind<[InvariantParam, CovariantParam, CovariantParam, ContravariantParam]>; export interface Array extends Kind.unary { return: this['arg0'][]; } /** * Special Kind for do notation */ export interface Do extends Kind.ternary { return: this['arg0'] extends string ? { [K in this['arg0'] | keyof this['arg1']]: K extends keyof this['arg1'] ? this['arg1'][K] : this['arg2']; } : never; } export interface DoName extends Kind.binary { return: this['arg0'] extends string ? Exclude : never; } type $ = { F: F; Args: Args; }; interface Generic extends Kind.unary { return: $; } export type F = Generic<'F'>; export type G = Generic<'G'>; export type H = Generic<'H'>; interface Generic2 extends Kind.binary { return: $; } export type F2 = Generic2<'F'>; export type G2 = Generic2<'G'>; export type H2 = Generic2<'H'>; interface Generic3 extends Kind.ternary { return: $; } export type F3 = Generic3<'F'>; export type G3 = Generic3<'G'>; export type H3 = Generic3<'H'>; interface Generic4 extends Kind.quaternary { return: $; } export type F4 = Generic4<'F'>; export type G4 = Generic4<'G'>; export type H4 = Generic4<'H'>; export interface Record extends Kind<[InvariantParam, CovariantParam]> { return: globalThis.Record; } export interface Iterable extends Kind.unary { return: globalThis.Iterable; } export interface Promise extends Kind.unary { return: globalThis.Promise; } export interface Or extends Kind.binary { return: this['arg0'] | this['arg1']; } export interface Basic extends Kind.nullary { return: T; } export type String = Basic; export type Number = Basic; export type Boolean = Basic; export type Null = Basic; export type Undefined = Basic; export type Symbol = Basic; export type BigInt = Basic; export type Date = Basic; export type RegExp = Basic; export type Error = Basic; export type Any = Basic; export type Unknown = Basic; export type Never = Basic; export type Void = Basic; export {}; }