@darkobits/valida
Version:
Type-aware object validator.
107 lines (106 loc) • 4.29 kB
TypeScript
import type { Options as DeepMergeOptions } from 'deepmerge';
import type { Ow, BasePredicate } from 'ow';
import type { DeepPartial, DeepRequired, Exact, Merge, NonEmptyObject } from 'ts-essentials';
/**
* Optional array merging function. Forwarded to `deepmerge`.
*/
export declare type ArrayMerge = (target: Array<any>, source: Array<any>, options?: DeepMergeOptions) => Array<any>;
/**
* Represents a generic class constructor.
*/
export declare type Constructor<T> = new (...args: Array<any>) => T;
/**
* Provided a Constructor type, unwraps its prototype / instance type.
*/
export declare type Prototype<C> = C extends Constructor<infer P> ? P : never;
/**
* Provided a Constructor or Prototype and a method name, returns the type for
* that method.
*/
export declare type MethodType<C extends Constructor<any> | Prototype<any>, K extends (keyof Prototype<C> | keyof C)> = C extends Constructor<any> ? K extends keyof Prototype<C> ? Prototype<C>[K] extends (this: Prototype<C>, ...args: Array<any>) => any ? Prototype<C>[K] : never : never : C extends Prototype<any> ? K extends keyof C ? C[K] extends (this: Prototype<C>, ...args: Array<any>) => any ? C[K] : never : never : never;
/**
* Object passed to method decorators.
*/
export interface MethodDecoratorContext<C extends Constructor<any>, K extends keyof Prototype<C>> {
args: Parameters<MethodType<C, K>>;
method: MethodType<C, K>;
instance: Prototype<C>;
}
/**
* Signature of method decorators.
*/
export declare type MethodDecorator<C extends Constructor<any>, K extends keyof Prototype<C>> = (ctx: MethodDecoratorContext<C, K>) => ReturnType<MethodType<C, K>>;
/**
* Defines an object with zero keys.
*/
export declare type EmptyObject<T extends {}> = keyof T extends never ? T : never;
/**
* Provided a type such as 'foo' | 'bar' | 'baz', widens it to 'string'. This
* is needed to ensure that predicates like ow.string are valid for narrow type
* literals.
*/
export declare type WidenLiterals<T> = T extends boolean ? boolean : T extends string ? string : T extends number ? number : T;
/**
* Deeply wraps a type into predicates.
*/
export declare type PredicateFor<T> = T extends BasePredicate<infer U> ? BasePredicate<U> : BasePredicate<T>;
/**
* Deeply wraps a type into predicates. If the type is an object, maps its keys
* into predicates while leaving the root intact.
*/
export declare type PredicateObjectFor<T> = T extends BasePredicate ? T : T extends object ? T extends NonEmptyObject<T> ? {
[K in keyof T]: PredicateFor<T[K]>;
} : never : BasePredicate<T>;
/**
* Deeply unwraps a predicate type or predicate object type into its shape.
*/
export declare type ShapeFor<T> = T extends BasePredicate<infer P> ? P : {
[K in keyof T]: ShapeFor<T[K]>;
};
export declare type ValidationResult<T, D> = Exact<T, ShapeFor<T>> extends never ? Merge<ShapeFor<T>, DeepRequired<D>> : T;
/**
* Deeply unwraps a predicate type into its generic shape, making each property
* optional.
*/
export declare type DefaultsFor<T> = T extends object ? DeepPartial<ShapeFor<T>> : ShapeFor<T>;
/**
* Object returned by a SpecFn.
*/
export interface CreateValidatorOptions<T, D> {
/**
* Optionally provide a descriptive name for the object being validated. This
* will be used as an `ow` label.
*/
name?: string;
/**
* Defines the intended shape for valid objects using `ow` predicates.
*
* Note: If the root value is a plain object, it will be wrapped in
* `partialShape` by default. If your spec requires an exact shape, use
* `exactShape` at the root.
*/
spec: PredicateFor<T> | PredicateObjectFor<T>;
/**
* Optional defaults to merge into user-provided values before performing
* validation.
*/
defaults?: D;
/**
* Optional array merging function. Forwarded to `deepmerge`.
*/
arrayMerge?: ArrayMerge;
}
/**
* Object passed to a `SpecFn`.
*/
export interface CreateValidatorContext {
ow: Ow;
}
/**
* Function passed to `createValidator`.
*/
export declare type SpecFn<S, D> = (context: CreateValidatorContext) => CreateValidatorOptions<S, D>;
/**
* Signature of validator functions.
*/
export declare type Validator<T, D> = (value: any) => ValidationResult<T, D>;