UNPKG

@lucaspaganini/value-objects

Version:

TypeScript first validation and class creation library

82 lines (81 loc) 3.55 kB
import { ValueObject, ValueObjectContructor, VOCRawInit, VORaw } from './value-object'; export declare type Noneable = undefined | null; export interface VOOptionalInstance<VO extends ValueObject<any>, None extends Noneable> { value: VO | None; isSome(): boolean; isNone(): boolean; valueOf(): VORaw<VO> | None; } export interface VOOptionalConstructor<VOC extends ValueObjectContructor, None extends Noneable> { new (r: VOCRawInit<VOC> | None): VOOptionalInstance<InstanceType<VOC>, None>; } /** * Function to create an optional value object constructor. * * @template VOC Value object constructor to make optional. * @template None Values that represent nothing. Defaults to `undefined`. * @param VOC Value object constructor to make optional. * @param nones Values that represent nothing. Defaults to `[undefined]`. * @returns Class constructor that accepts a None or the given * value object raw initial value for instantiation and returns * that value or the None value when {@link VOOptionalInstance.valueOf} is called. * * * The class created by `VOOptional` ({@link VOOptionalInstance}) wraps the * inner class and exposes it through the `value` property when it's instantiated. * Calling {@link VOOptionalInstance.valueOf} will either return the `None` value * or the `valueOf()` from the inner class. * * @example * ```typescript * class Name extends VOString({ trim: true, maxLength: 256, minLength: 1 }) {} * new Name('Lucas Paganini'); // OK * new Name(undefined); // Compilation error: Not a string * new Name(null); // Compilation error: Not a string * * class OptionalName extends VOOptional(Name) {} * new OptionalName('Lucas Paganini'); // OK * new OptionalName(undefined); // OK * new OptionalName(null); // Compilation error: Expects string | undefined * * const name = new Name('Lucas Paganini'); // OK * name.valueOf(); // "Lucas Paganini" * * const optional1 = new OptionalName('Lucas Paganini'); // OK * optional1.value; // Name instance * optional1.valueOf(); // "Lucas Paganini" * * const optional2 = new OptionalName(undefined); // OK * optional2.value; // undefined * optional2.valueOf(); // undefined * ``` * * This function has no options but it does accept a second parameter which * indicates what values should be considered nothing. * For default, it only accepts `undefined`, but you can change that to * _also_ accept `null` or maybe to _just_ accept `null`. * * @example * ```typescript * class Name extends VOString({ trim: true, maxLength: 256, minLength: 1 }) {} * new Name('Lucas Paganini'); // OK * new Name(undefined); // Compilation error: Not a string * new Name(null); // Compilation error: Not a string * * class OptionalName1 extends VOOptional(Name) {} * new OptionalName1('Lucas Paganini'); // OK * new OptionalName1(undefined); // OK * new OptionalName1(null); // Compilation error: Expects string | undefined * * class OptionalName2 extends VOOptional(Name, [undefined, null]) {} * new OptionalName2('Lucas Paganini'); // OK * new OptionalName2(undefined); // OK * new OptionalName2(null); // OK * * class OptionalName3 extends VOOptional(Name, [null]) {} * new OptionalName3('Lucas Paganini'); // OK * new OptionalName3(undefined); // Compilation error: Expects string | null * new OptionalName3(null); // OK * ``` */ export declare const VOOptional: <VOC extends ValueObjectContructor<any, any>, None extends Noneable = undefined>(VOC: VOC, nones?: None[] | undefined) => VOOptionalConstructor<VOC, None>;