@lucaspaganini/value-objects
Version:
TypeScript first validation and class creation library
62 lines (61 loc) • 2.79 kB
TypeScript
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>;