UNPKG

alwz

Version:

Extendable library for typecasting

215 lines 8.69 kB
/// <reference types="node" /> export type IS<T> = (input?: unknown) => input is T; export declare function isIS<T>(input?: unknown): input is IS<T>; export declare function assertIS<T>(input?: unknown): true | never; export type Fallback<OUTPUT> = (input?: unknown) => OUTPUT | never; export declare function isFallback<OUTPUT>(input?: unknown): input is Fallback<OUTPUT>; export declare function assertFallback<OUTPUT>(input?: unknown): true | never; export type Conversion<INPUT, OUTPUT> = (this: Converter<OUTPUT>, input: INPUT) => OUTPUT; export declare function isConversion<INPUT, OUTPUT>(input: unknown): input is Conversion<INPUT, OUTPUT>; export declare function assertConversion<INPUT, OUTPUT>(input: unknown): true | never; type TypesMap = { undefined: undefined; boolean: boolean; number: number; bigint: bigint; string: string; symbol: symbol; }; type TypeConversions<OUTPUT> = { [Name in keyof TypesMap]: Conversion<TypesMap[Name], OUTPUT>; }; type TypeConversion<Name, OUTPUT> = Name extends keyof TypeConversions<OUTPUT> ? TypeConversions<OUTPUT>[Name] : never; /** * @description converts input data to specific type * - at first checks if conversion is necessary * - attempts conversion based on the input data type * - searches for suitable conversions among registered * - calls a fallback function * * @example <caption>converter creation</caption> * const positive = new Converter( * (input) => typeof input === 'number' && input > 0, * (input) => input === 0 ? 0.1 : 0.2 * ); * * positive * .undefined(() => 0.3) * .boolean((i) => i ? 1 : 0.4) * .number(function(i) { * const result = Math.abs(i) * return this.is(result) ? result : this.fallback(i); * }) * .string((i) => positive.convert(Number(i))) * .symbol((i) => positive.convert(Symbol.keyFor(i))) * .bigint((i) => positive.convert(Number(i))) * .register(Array.isArray, (i) => positive.convert(i[0])) * .register((i) => i === null, (i) => 0.5); * * positive.convert(1); // 1 * positive.convert(0); // 0.1 (fallback) * positive.convert(NaN); // 0.2 (fallback) * positive.convert(undefined); // 0.3 (has own handler) * positive.convert(false); // 0.4 (has own handler) * positive.convert(null); // 0.5 (has own handler) * positive.convert(2n); // 2 * positive.convert(-3); // 3 * positive.convert('4'); // 4 * positive.convert([5, 6]); // 5 * * @example <caption>conversion with prohibited input types</caption> * const converter = new Converter( * (input) => typeof input === 'number', * (input) => { * throw new Error('unknown input data type:' + input); * }) * .string((i) => { * throw new Error('string input is forbidden:' + i); * }) * .boolean(Number) * .register(Array.isArray, (i) => converter.convert(i[0])); * * converter.convert(true); // 1 * converter.convert(2); // 2 * converter.convert('3'); // Error * converter.convert([4]); // 4 * converter.convert(Promise.resolve(5)); // Error */ export declare class Converter<OUTPUT> { static InvalidTypeCheckFunction: { new (message?: string | undefined, value?: unknown, options?: unknown): { value?: unknown; throw(): void; name: string; message: string; stack?: string | undefined; }; captureStackTrace(targetObject: object, constructorOpt?: Function | undefined): void; prepareStackTrace?: ((err: Error, stackTraces: NodeJS.CallSite[]) => any) | undefined; stackTraceLimit: number; }; static InvalidFallbackFunction: { new (message?: string | undefined, value?: unknown, options?: unknown): { value?: unknown; throw(): void; name: string; message: string; stack?: string | undefined; }; captureStackTrace(targetObject: object, constructorOpt?: Function | undefined): void; prepareStackTrace?: ((err: Error, stackTraces: NodeJS.CallSite[]) => any) | undefined; stackTraceLimit: number; }; static InvalidConversionFunction: { new (message?: string | undefined, value?: unknown, options?: unknown): { value?: unknown; throw(): void; name: string; message: string; stack?: string | undefined; }; captureStackTrace(targetObject: object, constructorOpt?: Function | undefined): void; prepareStackTrace?: ((err: Error, stackTraces: NodeJS.CallSite[]) => any) | undefined; stackTraceLimit: number; }; static InvalidConverter: { new (message?: string | undefined, value?: unknown, options?: unknown): { value?: unknown; throw(): void; name: string; message: string; stack?: string | undefined; }; captureStackTrace(targetObject: object, constructorOpt?: Function | undefined): void; prepareStackTrace?: ((err: Error, stackTraces: NodeJS.CallSite[]) => any) | undefined; stackTraceLimit: number; }; protected _is: IS<OUTPUT>; protected _fallback: Fallback<OUTPUT>; protected _types: Partial<TypeConversions<OUTPUT>>; protected _conversions: Map<IS<any>, Conversion<any, OUTPUT>>; /** * @param {IS<OUTPUT>} is - initial input data type check (predicate). determines if any conversion is necessary * @param {Fallback<OUTPUT>} fallback - fallback value generator. runs if none of the available conversions are suitable */ constructor(is: IS<OUTPUT>, fallback: Fallback<OUTPUT>); get is(): IS<OUTPUT>; set is(is: IS<OUTPUT>); get fallback(): Fallback<OUTPUT>; set fallback(fallback: Fallback<OUTPUT>); get types(): Partial<TypeConversions<OUTPUT>>; get conversions(): Array<[IS<unknown>, Conversion<unknown, OUTPUT>]>; /** * @description converts data according to saved conversion rules * @param {*} input - input data */ convert: (input?: unknown) => OUTPUT; /** * @description adds conversion function for `INPUT` type * @param {IS<INPUT>} is - input data type check (predicate), determines if input can be processed by `conversion` * @param {Conversion<INPUT, OUTPUT>} conversion - `INPUT` to `OUTPUT` conversion function */ register<INPUT>(is: IS<INPUT>, conversion: Conversion<INPUT, OUTPUT>): this; /** * @description removes conversion for `INPUT` type * @param {IS<INPUT>} is - input type check (predicate) */ unregister<INPUT>(is: IS<INPUT>): this; /** * @description set conversion rule for type `name` if `conversion` is defined or unset if undefined * @param {string} name - one of types (`typeof` result) * @param {Conversion} [conversion] */ type<Name extends keyof TypesMap>(name: Name, conversion?: TypeConversion<Name, OUTPUT>): this; /** * @description conversion rule setter for `undefined` input * @param {Conversion} [conversion] */ undefined(conversion?: Conversion<undefined, OUTPUT>): this; /** * @description conversion rule setter for `boolean` input * @param {Conversion} [conversion] */ boolean(conversion?: Conversion<boolean, OUTPUT>): this; /** * @description conversion rule setter for `number` input * @param {Conversion} [conversion] */ number(conversion?: Conversion<number, OUTPUT>): this; /** * @description conversion rule setter for `bigint` input * @param {Conversion} [conversion] */ bigint(conversion?: Conversion<bigint, OUTPUT>): this; /** * @description conversion rule setter for `string` input * @param {Conversion} [conversion] */ string(conversion?: Conversion<string, OUTPUT>): this; /** * @description conversion rule setter for `symbol` input * @param {Conversion} [conversion] */ symbol(conversion?: Conversion<symbol, OUTPUT>): this; /** * @example * const converter = new Converter( * (i) => typeof i === 'number', * () => 0 * ) * .undefined(() => 1); * * const clone = converter * .clone() * .undefined(() => 2); * * converter.convert(); // 1 * clone.convert(); // 2 */ clone(): Converter<OUTPUT>; static build<OUTPUT>(is: IS<OUTPUT>, fallback: Fallback<OUTPUT>, types?: Partial<TypeConversions<OUTPUT>>, conversions?: Iterable<[IS<any>, Conversion<any, OUTPUT>]>): Converter<OUTPUT>; static is: (input?: unknown) => boolean; static assert(input?: unknown): boolean; } export default Converter; //# sourceMappingURL=Converter.d.ts.map