lib0
Version:
> Monorepo of isomorphic utility functions
323 lines • 11.9 kB
TypeScript
/**
* @template T
*/
export class $Schema<T> {
/**
* Use `schema.validate(obj)` with a typed parameter that is already of typed to be an instance of
* Schema. Validate will check the structure of the parameter and return true iff the instance
* really is an instance of Schema.
*
* @param {T} o
* @return {boolean}
*/
validate(o: T): boolean;
/**
* Similar to validate, but this method accepts untyped parameters.
*
* @param {any} _o
* @return {_o is T}
*/
check(_o: any): _o is T;
/**
* @type {$Schema<T?>}
*/
get nullable(): $Schema<T | null>;
/**
* @type {$Optional<$Schema<T>>}
*/
get optional(): $Optional<$Schema<T>>;
/**
* Cast a variable to a specific type. Returns the casted value, or throws an exception otherwise.
* Use this if you know that the type is of a specific type and you just want to convince the type
* system.
*
* **Do not rely on these error messages!**
* Performs an assertion check only if not in a production environment.
*
* @param {any} o
* @return {o extends T ? T : never}
*/
cast(o: any): any extends T ? T : never;
/**
* Ensures that a variable is a a specific type. Returns the value, or throws an exception if the assertion check failed.
* Use this if you know that the type is of a specific type and you just want to convince the type
* system.
*
* Can be useful when defining lambdas: `s.lambda(s.$number, s.$void).ensure((n) => n + 1)`
*
* **Do not rely on these error messages!**
* Performs an assertion check if not in a production environment.
*
* @param {T} o
* @return {o extends T ? T : never}
*/
ensure(o: T): T extends T ? T : never;
get [schemaSymbol](): boolean;
}
/**
* @template {(new (...args:any[]) => any) | ((...args:any[]) => any)} C
* @extends {$Schema<C extends ((...args:any[]) => infer T) ? T : (C extends (new (...args:any[]) => any) ? InstanceType<C> : never)>}
*/
export class $ConstructedBy<C extends (new (...args: any[]) => any) | ((...args: any[]) => any)> extends $Schema<C extends (...args: any[]) => infer T ? T : C extends new (...args: any[]) => any ? InstanceType<C> : never> {
/**
* @param {C} c
*/
constructor(c: C);
v: C;
/**
* @param {any} o
* @return {o is C extends ((...args:any[]) => infer T) ? T : (C extends (new (...args:any[]) => any) ? InstanceType<C> : never)} o
*/
check(o: any): o is C extends ((...args: any[]) => infer T_1) ? T_1 : (C extends (new (...args: any[]) => any) ? InstanceType<C> : never);
}
export function constructedBy<C extends (new (...args: any[]) => any) | ((...args: any[]) => any)>(c: C): CastToSchema<$ConstructedBy<C>>;
/**
* @template {LiteralType} T
* @extends {$Schema<T>}
*/
export class $Literal<T extends LiteralType> extends $Schema<T> {
/**
* @param {Array<T>} literals
*/
constructor(literals: Array<T>);
v: T[];
}
export function literal<T extends LiteralType[]>(...literals: T): CastToSchema<$Literal<T[number]>>;
/**
* @template {{ [key: string|symbol|number]: $Schema<any> }} S
* @typedef {{ [Key in keyof S as S[Key] extends $Optional<$Schema<any>> ? Key : never]?: S[Key] extends $Optional<$Schema<infer Type>> ? Type : never } & { [Key in keyof S as S[Key] extends $Optional<$Schema<any>> ? never : Key]: S[Key] extends $Schema<infer Type> ? Type : never }} $ObjectToType
*/
/**
* @template {{[key:string|symbol|number]: $Schema<any>}} S
* @extends {$Schema<$ObjectToType<S>>}
*/
export class $Object<S extends {
[key: string | symbol | number]: $Schema<any>;
}> extends $Schema<$ObjectToType<S>> {
/**
* @param {S} v
*/
constructor(v: S);
v: S;
}
export function object<S extends {
[key: string | symbol | number]: $Schema<any>;
}>(def: S): $Schema<{ [Key in keyof S as S[Key] extends $Optional<$Schema<any>> ? Key : never]?: S[Key] extends $Optional<$Schema<infer Type>> ? Type : never; } & { [Key in keyof S as S[Key] extends $Optional<$Schema<any>> ? never : Key]: S[Key] extends $Schema<infer Type> ? Type : never; }>;
/**
* @template {$Schema<string|number|symbol>} Keys
* @template {$Schema<any>} Values
* @extends {$Schema<Record<Keys extends $Schema<infer K> ? K : never,Values extends $Schema<infer T> ? T : never>>}
*/
export class $Record<Keys extends $Schema<string | number | symbol>, Values extends $Schema<any>> extends $Schema<Record<Keys extends $Schema<infer K> ? K : never, Values extends $Schema<infer T> ? T : never>> {
/**
* @param {Keys} keys
* @param {Values} values
*/
constructor(keys: Keys, values: Values);
keys: Keys;
values: Values;
/**
* @param {any} o
* @return {o is Record<Keys extends $Schema<infer K> ? K : never,Values extends $Schema<infer T> ? T : never>}
*/
check(o: any): o is Record<Keys extends $Schema<infer K_1> ? K_1 : never, Values extends $Schema<infer T_1> ? T_1 : never>;
}
export function record<Keys extends $Schema<string | number | symbol>, Values extends $Schema<any>>(keys: Keys, values: Values): CastToSchema<$Record<Keys, Values>>;
/**
* @template {$Schema<any>[]} S
* @extends {$Schema<{ [Key in keyof S]: S[Key] extends $Schema<infer Type> ? Type : never }>}
*/
export class $Tuple<S extends $Schema<any>[]> extends $Schema<{ [Key in keyof S]: S[Key] extends $Schema<infer Type> ? Type : never; }> {
/**
* @param {S} v
*/
constructor(v: S);
v: S;
/**
* @param {any} o
* @return {o is { [K in keyof S]: S[K] extends $Schema<infer Type> ? Type : never }}
*/
check(o: any): o is { [K in keyof S]: S[K] extends $Schema<infer Type_1> ? Type_1 : never; };
}
export function tuple<T extends Array<$Schema<any>>>(...def: T): CastToSchema<$Tuple<T>>;
/**
* @template {$Schema<any>} S
* @extends {$Schema<Array<S extends $Schema<infer T> ? T : never>>}
*/
export class $Array<S extends $Schema<any>> extends $Schema<(S extends $Schema<infer T> ? T : never)[]> {
/**
* @param {Array<S>} v
*/
constructor(v: Array<S>);
/**
* @type {$Schema<S extends $Schema<infer T> ? T : never>}
*/
v: $Schema<S extends $Schema<infer T_1> ? T_1 : never>;
/**
* @param {any} o
* @return {o is Array<S extends $Schema<infer T> ? T : never>} o
*/
check(o: any): o is Array<S extends $Schema<infer T_1> ? T_1 : never>;
}
export function array<T extends Array<$Schema<any>>>(...def: T): $Schema<Array<T extends Array<$Schema<infer S>> ? S : never>>;
/**
* @template T
* @extends {$Schema<T>}
*/
export class $InstanceOf<T> extends $Schema<T> {
/**
* @param {new (...args:any) => T} constructor
*/
constructor(constructor: new (...args: any) => T);
v: new (...args: any) => T;
}
export function instance<T>(c: new (...args: any) => T): $Schema<T>;
/**
* @template {$Schema<any>[]} Args
* @typedef {(...args:UnwrapArray<TuplePop<Args>>)=>Unwrap<TupleLast<Args>>} _LArgsToLambdaDef
*/
/**
* @template {Array<$Schema<any>>} Args
* @extends {$Schema<_LArgsToLambdaDef<Args>>}
*/
export class $Lambda<Args extends Array<$Schema<any>>> extends $Schema<_LArgsToLambdaDef<Args>> {
/**
* @param {Args} args
*/
constructor(args: Args);
len: number;
args: $Schema<any[]>;
res: $Schema<any>;
}
export function lambda<Args extends $Schema<any>[]>(...args: Args): $Schema<(...args: UnwrapArray<TuplePop<Args>>) => Unwrap<TupleLast<Args>>>;
/**
* @template {Array<$Schema<any>>} T
* @extends {$Schema<Intersect<UnwrapArray<T>>>}
*/
export class $Intersection<T extends Array<$Schema<any>>> extends $Schema<Intersect<UnwrapArray<T>>> {
/**
* @param {T} v
*/
constructor(v: T);
/**
* @type {T}
*/
v: T;
}
export function intersect<T extends $Schema<any>[]>(...def: T): CastToSchema<$Intersection<T>>;
/**
* @template S
* @extends {$Schema<S>}
*/
export class $Union<S> extends $Schema<S> {
static schema: $Schema<$Union<unknown>>;
/**
* @param {Array<$Schema<S>>} v
*/
constructor(v: Array<$Schema<S>>);
v: $Schema<S>[];
}
export function union<T extends Array<$Schema<any>>>(...def: T): CastToSchema<$Union<T extends [] ? never : (T extends Array<$Schema<infer S>> ? S : never)>>;
/**
* @type {$Schema<any>}
*/
export const any: $Schema<any>;
/**
* @type {$Schema<bigint>}
*/
export const bigint: $Schema<bigint>;
/**
* @type {$Schema<Symbol>}
*/
export const symbol: $Schema<Symbol>;
/**
* @type {$Schema<number>}
*/
export const number: $Schema<number>;
/**
* @type {$Schema<string>}
*/
export const string: $Schema<string>;
export { $undefined as undefined };
/**
* @type {$Schema<void>}
*/
export const $void: $Schema<void>;
export const $null: $Schema<null>;
/**
* Assert that a variable is of this specific type.
* The assertion check is only performed in non-production environments.
*
* @type {<T>(o:any,schema:$Schema<T>) => asserts o is T}
*/
export const assert: <T>(o: any, schema: $Schema<T>) => asserts o is T;
export type LiteralType = string | number | bigint | boolean | null | undefined;
export type AnyObject = {
[k: string | number | symbol]: any;
};
export type Unwrap<T> = T extends $Schema<infer X> ? X : T;
export type UnwrapArray<T extends readonly unknown[]> = T extends readonly [$Schema<infer First>, ...infer Rest] ? [First, ...UnwrapArray<Rest>] : [];
export type CastToSchema<T> = T extends $Schema<infer S> ? $Schema<S> : never;
export type TupleLast<Arr extends unknown[]> = Arr extends [...unknown[], infer L] ? L : never;
export type TuplePop<Arr extends unknown[]> = Arr extends [...infer Fs, unknown] ? Fs : never;
export type Intersect<T extends readonly unknown[]> = T extends [] ? {} : T extends [infer First] ? First : T extends [infer First, ...infer Rest] ? First & Intersect<Rest> : never;
export type $ObjectToType<S extends {
[key: string | symbol | number]: $Schema<any>;
}> = { [Key in keyof S as S[Key] extends $Optional<$Schema<any>> ? Key : never]?: S[Key] extends $Optional<$Schema<infer Type>> ? Type : never; } & { [Key in keyof S as S[Key] extends $Optional<$Schema<any>> ? never : Key]: S[Key] extends $Schema<infer Type> ? Type : never; };
export type _LArgsToLambdaDef<Args extends $Schema<any>[]> = (...args: UnwrapArray<TuplePop<Args>>) => Unwrap<TupleLast<Args>>;
/**
* @template {$Schema<any>} S
* @extends $Schema<Unwrap<S>|undefined>
*/
declare class $Optional<S extends $Schema<any>> extends $Schema<Unwrap<S> | undefined> {
/**
* @param {S} s
*/
constructor(s: S);
s: S;
get [isOptionalSymbol](): boolean;
}
/**
* @typedef {string|number|bigint|boolean|null|undefined} LiteralType
*/
/**
* @typedef {{ [k:string|number|symbol]: any }} AnyObject
*/
/**
* @template T
* @typedef {T extends $Schema<infer X> ? X : T} Unwrap
*/
/**
* @template {readonly unknown[]} T
* @typedef {T extends readonly [$Schema<infer First>, ...infer Rest] ? [First, ...UnwrapArray<Rest>] : [] } UnwrapArray
*/
/**
* @template T
* @typedef {T extends $Schema<infer S> ? $Schema<S> : never} CastToSchema
*/
/**
* @template {unknown[]} Arr
* @typedef {Arr extends [...unknown[], infer L] ? L : never} TupleLast
*/
/**
* @template {unknown[]} Arr
* @typedef {Arr extends [...infer Fs, unknown] ? Fs : never} TuplePop
*/
/**
* @template {readonly unknown[]} T
* @typedef {T extends []
* ? {}
* : T extends [infer First]
* ? First
* : T extends [infer First, ...infer Rest]
* ? First & Intersect<Rest>
* : never
* } Intersect
*/
declare const schemaSymbol: unique symbol;
/**
* @type {$Schema<undefined>}
*/
declare const $undefined: $Schema<undefined>;
declare const isOptionalSymbol: unique symbol;
//# sourceMappingURL=schema.d.ts.map