joiful
Version:
TypeScript Declarative Validation. Decorate your class properties to validate them using Joi.
79 lines (78 loc) • 3.35 kB
TypeScript
import 'reflect-metadata';
import * as Joi from 'joi';
export declare const getJoi: (options?: {
joi?: typeof Joi;
} | undefined) => Joi.Root;
export declare const WORKING_SCHEMA_KEY = "tsdv:working-schema";
export declare const SCHEMA_KEY = "tsdv:schema";
export declare const JOI_VERSION: Version;
export declare type WorkingSchema = {
[index: string]: Joi.Schema;
};
export interface Constructor<T> {
new (...args: any[]): T;
}
export declare type AnyClass = Constructor<any>;
export declare type StringKey<T> = Extract<keyof T, string>;
export declare type StringOrSymbolKey<T> = Extract<keyof T, string | symbol>;
/**
* If a given type extends the desired type, return the given type. Otherwise, return the desired type.
* So, you can do stuff like this:
*
* ```typescript
* interface Foo {
* bar: null;
* baz: number;
* boz: string;
* biz: string | null;
* }
*
* const bars1: AllowUnions<Foo['baz'], number, Foo['baz']>[] = [
* 'sdf', // Type 'string' is not assignable to type 'number'.
* null, // Type 'null' is not assignable to type 'number'.
* 123
* ];
*
* const bars2: AllowUnions<Foo['boz'], string, Foo['boz']>[] = [
* 'sdf',
* null, // Type 'null' is not assignable to type 'string'.
* 123 // Type 'number' is not assignable to type 'string'.
* ];
*
* const bars3: AllowUnions<Foo['biz'], string, Foo['biz']>[] = [
* 'sdf',
* null,
* 123 // Type 'number' is not assignable to type 'string | null'.
* ];
* ```
*
* Notice that you pass the TOriginal type parameter, which is identical to the TType type parameter. This is because
* the "extends" condition will narrow the type of TType to just TDesired. So, "string | null" will be narrowed to
* "string", but we actually want to return the original "string | null".
*
* By returning the TDesired when there's no match, we get nice error messages that state what the desired type was.
*/
export declare type AllowUnions<TType, TDesired, TOriginal> = TType extends TDesired ? TOriginal : TDesired;
export declare type MapAllowUnions<TObject, TKey extends keyof TObject, TDesired> = {
[K in TKey]: AllowUnions<TObject[K], TDesired, TObject[K]>;
};
export declare type TypedPropertyDecorator<TPropertyType> = (<TClass extends MapAllowUnions<TClass, TKey, TPropertyType>, TKey extends StringOrSymbolKey<TClass>>(target: TClass, propertyKey: TKey) => void);
export declare function getWorkingSchema<TClass>(target: TClass): WorkingSchema | undefined;
export declare function getMergedWorkingSchemas(target: object): WorkingSchema | undefined;
export declare function getJoiSchema(Class: AnyClass, joi: Pick<typeof Joi, 'object'>): Joi.ObjectSchema | undefined;
export declare function updateWorkingSchema<TClass, TKey extends StringOrSymbolKey<TClass>>(target: TClass, propertyKey: TKey, schema: Joi.Schema): void;
export interface Version {
major: string;
minor: string;
patch: string;
}
export declare function parseVersionString(version: string): {
major: string;
minor: string;
patch: string;
};
export declare function getJoiVersion(joi: typeof Joi | undefined): Version;
export declare class IncompatibleJoiVersion extends Error {
constructor(actualVersion: Version);
}
export declare function checkJoiIsCompatible(joi: typeof Joi | undefined): void;