rivo
Version:
🤖 The ultimate library you need for composable type-level programming in TypeScript, powered by HKT.
109 lines (100 loc) • 2.85 kB
TypeScript
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;
}