UNPKG

@lucaspaganini/value-objects

Version:

TypeScript first validation and class creation library

62 lines (61 loc) 2.79 kB
export interface VOSetOptions<Strict extends boolean = boolean> { /** * Whether it should expect the set elements literal types or their closest * supersets (eg. `true => boolean` and `"abc" => string`) for instantiation. * Defaults to false. */ strict?: Strict; } export declare type Setable = string | number | boolean; export declare type VOSetRaw<Element extends Setable, Strict extends boolean> = Strict extends true ? Element : (Element extends number ? number : never) | (Element extends string ? string : never) | (Element extends boolean ? boolean : never); export interface VOSetInstance<Element extends Setable> { valueOf(): Element; } export interface VOSetConstructor<Element extends Setable, Strict extends boolean> { new (r: VOSetRaw<Element, Strict>): VOSetInstance<Element>; } /** * Function to create a set of elements value object constructor. * * @template Element Literal type of the set elements. * @template Strict Literal boolean indicating the `options.strict` flag. * @param elements Elements in the set, they must be {@link Setable}. * @param options Customizations for the returned class constructor. * @returns Class constructor that accepts a set element for instantiation * and returns that element when {@link VOSetInstance.valueOf} is called. * * @example * ```typescript * class TestSet extends VOSet([123, 'abc']) {} * new TestSet('abc'); // OK * new TestSet(''); // Runtime error: Not in set * new TestSet(1); // Runtime error: Not in set * new TestSet(false); // Compilation error: Expects string | number * ``` * * The coolest part of `VOSet` are definitely the conditional types * in {@link VOSetRaw} that decide what is expected for instantiation and * the customization of this behaviour using the `options.strict` flag. * See the examples below. * * @example * ```typescript * class NonStrictSet extends VOSet([123, true]) {} * new NonStrictSet(true); // OK * new NonStrictSet('abc'); // Compilation error: Expects number | boolean * new NonStrictSet(''); // Compilation error: Expects number | boolean * new NonStrictSet(1); // Runtime error: Not in set * new NonStrictSet(false); // Runtime error: Not in set * ``` * * @example * ```typescript * class StrictSet extends VOSet([123, true], { strict: true }) {} * new StrictSet(true); // OK * new StrictSet('abc'); // Compilation error: Expects true | 123 * new StrictSet(''); // Compilation error: Expects true | 123 * new StrictSet(1); // Compilation error: Expects true | 123 * new StrictSet(false); // Compilation error: Expects true | 123 * ``` */ export declare const VOSet: <Element extends Setable, Strict extends boolean>(elements: Element[], options?: VOSetOptions<Strict>) => VOSetConstructor<Element, Strict>;