UNPKG

rivo

Version:

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

109 lines (100 loc) • 2.85 kB
import type ShowFn from "./Show"; import type { Fn1 } from "../../HKT"; import type { ValueOf } from "../../Obj/ValueOf"; import type { Eq, Lazied, Lazied$Get } from "../../helpers"; /** * A type class for types that can be converted to a string. */ export type Show = Lazied$Get<ShowL>; /** * {@link Lazied} version of {@link Show}. */ export type ShowL = Lazied<ShowImpl[keyof ShowImpl][0]>; /** * Type class constraints for type class {@link Show}. */ export interface TypeClass$$Show<T> { Show: Fn1<T, string>; } /** * Implementations for type class {@link Show}. */ export interface ShowImpl {} /** * Helper type for implementing type class {@link Show}. * * @example * ```typescript * import type { Args, Fn2, Show } from "rivo"; * import type { TypeClass$$Show } from "rivo/typeclass"; * import type { Show as Show_ } from "rivo/typeclass/Show/Show"; * // ^^^^^^^^^^^^^ * // Use the internal implementation for `Show.Show` for better performance * * interface MyType<N extends number = number> { * value: N; * } * * declare module "rivo/typeclass/Show" { * interface ShowImpl { * MyType: ImplShowFor<MyType, MyType$$Show>; * // ^^^^^^ * // Can be any property key * } * } * * interface MyType$$Show extends TypeClass$$Show<MyType> { * Show: MyType$$Show$Show; * } * * interface MyType$$Show$Show extends Fn1<MyType, string> { * def: ([s]: Args<this>) => `MyType<${Show_<(typeof s)["value"]>}>`; * } * * type R = Show.Show<MyType<42>>; * // ^?: "MyType<42>" * ``` */ export type ImplShowFor<T, TypeClass extends TypeClass$$Show<T>> = [T, TypeClass]; /** * Get the matching entry of {@link ShowImpl} for `S`. * @private */ type _Show$GetMatch<S extends Show> = ValueOf<{ [P in keyof ShowImpl as S extends ShowImpl[P][0] ? P : never]: ShowImpl[P]; }>; /** * Get the constructor of `S` from {@link ShowImpl}. */ export type Show$GetConstruct<S extends Show> = Eq<S, Show> extends true ? Show : _Show$GetMatch<S> extends [infer T, unknown] ? T : never; /** * The **unsafe** version of {@link Show$GetConstruct} (i.e. no type checking with `S`). */ export type Show$GetConstructW<S> = S extends Show ? Show$GetConstruct<S> : never; /** * Get the type class of `S` from {@link ShowImpl}. */ export type Show$GetTypeClass<S extends Show> = _Show$GetMatch<S> extends [unknown, infer TypeClass extends TypeClass$$Show<any>] ? TypeClass : never; /** * The **unsafe** version of {@link Show$GetTypeClass} (i.e. no type checking with `S`). */ export type Show$GetTypeClassW<S> = S extends Show ? Show$GetTypeClass<S> : never; /*********** * Methods * ***********/ /** * Methods for `Show`. */ export namespace Show { /** * [Fn] Convert a `Show` instance to a string. * * Sig: `(s: Show) => string` */ export type Show = ShowFn; }