// Type definitions for yup 0.29 // Project: https://github.com/jquense/yup // Definitions by: Dominik Hardtke , // Vladyslav Tserman , // Moreton Bay Regional Council , // Sindre Seppola // Yash Kulshrestha // Vincent Pizzo // Robert Bullen // Yusuke Sato // Desmond Koh // Maurice de Beijer // Kalley Powell // Elías García // Ian Sanders // Jay Fong // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 3.6 export function reach(schema: Schema, path: string, value?: any, context?: any): Schema; export function addMethod>( schemaCtor: AnySchemaConstructor, name: string, method: (this: T, ...args: any[]) => T, ): void; export function ref(path: string, options?: { contextPrefix: string }): Ref; export function lazy(fn: (value: T) => Schema): Lazy; export function setLocale(customLocale: LocaleObject): void; export function isSchema(obj: any): obj is Schema; export const mixed: MixedSchemaConstructor; export const string: StringSchemaConstructor; export const number: NumberSchemaConstructor; export const boolean: BooleanSchemaConstructor; export const bool: BooleanSchemaConstructor; export const date: DateSchemaConstructor; export const array: ArraySchemaConstructor; export const object: ObjectSchemaConstructor; export type AnySchemaConstructor = | MixedSchemaConstructor | StringSchemaConstructor | NumberSchemaConstructor | BooleanSchemaConstructor | DateSchemaConstructor | ArraySchemaConstructor | ObjectSchemaConstructor; export type TestOptionsMessage = {}, R = any> = | string | ((params: Extra & Partial) => R); export interface Schema { type: string; clone(): this; label(label: string): this; meta(metadata: any): this; meta(): any; describe(): SchemaDescription; concat(schema: this): this; validate(value: any, options?: ValidateOptions): Promise; validateSync(value: any, options?: ValidateOptions): T; validateAt(path: string, value: T, options?: ValidateOptions): Promise; validateSyncAt(path: string, value: T, options?: ValidateOptions): T; isValid(value: any, options?: any): Promise; isValidSync(value: any, options?: any): value is T; cast(value?: any, options?: any): T; isType(value: any): value is T; strict(isStrict: boolean): this; strip(strip: boolean): this; withMutation(fn: (current: this) => void): void; default(value: any): this; default(): T; typeError(message?: TestOptionsMessage): this; notOneOf(arrayOfValues: any[], message?: MixedLocale['notOneOf']): this; when(keys: string | any[], builder: WhenOptions): this; transform(fn: TransformFunction): this; } // Note: Using `{} | null | undefined` allows excluding `null` & `undefined` // whereas using `any` as the default type would mean that `nullable(false)`, // `defined`, and `required` would all have no effect. export interface MixedSchemaConstructor { // tslint:disable-next-line:no-unnecessary-generics (): MixedSchema; // tslint:disable-next-line:no-unnecessary-generics new (options?: { type?: string; [key: string]: any }): MixedSchema; } export interface MixedSchema extends Schema { nullable(isNullable?: true): MixedSchema; nullable(isNullable: false): MixedSchema>; nullable(isNullable?: boolean): MixedSchema; required(message?: TestOptionsMessage): MixedSchema>; defined(): MixedSchema>; notRequired(): MixedSchema; optional(): MixedSchema; concat(schema: this): this; concat(schema: Schema): MixedSchema; oneOf( arrayOfValues: ReadonlyArray, message?: MixedLocale['oneOf'], ): MixedSchema>; equals( arrayOfValues: ReadonlyArray, message?: MixedLocale['oneOf'], ): MixedSchema>; test(name: string, message: TestOptionsMessage, test: AssertingTestFunction): MixedSchema; test(name: string, message: TestOptionsMessage, test: TestFunction): this; test(options: AssertingTestOptions>): MixedSchema; test(options: TestOptions>): this; } export interface StringSchemaConstructor { (): StringSchema; new (): StringSchema; } export interface StringSchema extends Schema { length(limit: number | Ref, message?: StringLocale['length']): StringSchema; min(limit: number | Ref, message?: StringLocale['min']): StringSchema; max(limit: number | Ref, message?: StringLocale['max']): StringSchema; matches( regex: RegExp, messageOrOptions?: | StringLocale['matches'] | { message?: StringLocale['matches']; excludeEmptyString?: boolean }, ): StringSchema; email(message?: StringLocale['email']): StringSchema; url(message?: StringLocale['url']): StringSchema; uuid(message?: StringLocale['uuid']): StringSchema; ensure(): StringSchema; trim(message?: StringLocale['trim']): StringSchema; lowercase(message?: StringLocale['lowercase']): StringSchema; uppercase(message?: StringLocale['uppercase']): StringSchema; nullable(isNullable?: true): StringSchema; nullable(isNullable: false): StringSchema>; nullable(isNullable?: boolean): StringSchema; required(message?: TestOptionsMessage): StringSchema>; defined(): StringSchema>; notRequired(): StringSchema; oneOf( arrayOfValues: ReadonlyArray, message?: MixedLocale['oneOf'], ): StringSchema>; equals( arrayOfValues: ReadonlyArray, message?: MixedLocale['oneOf'], ): StringSchema>; /* All TestFunction generics are intentionally T with (undefined | null) as previous .required / .defined / .nullable will narrow out those types, and tests run for (undefined | null) even if they're not allowed. */ test(name: string, message: TestOptionsMessage, test: TestFunction): this; test(name: string, message: TestOptionsMessage, test: AssertingTestFunction): StringSchema; test(options: AssertingTestOptions>): StringSchema; test(options: TestOptions>): this; optional(): StringSchema; } export interface NumberSchemaConstructor { (): NumberSchema; new (): NumberSchema; } export interface NumberSchema extends Schema { min(limit: number | Ref, message?: NumberLocale['min']): NumberSchema; max(limit: number | Ref, message?: NumberLocale['max']): NumberSchema; lessThan(limit: number | Ref, message?: NumberLocale['lessThan']): NumberSchema; moreThan(limit: number | Ref, message?: NumberLocale['moreThan']): NumberSchema; positive(message?: NumberLocale['positive']): NumberSchema; negative(message?: NumberLocale['negative']): NumberSchema; integer(message?: NumberLocale['integer']): NumberSchema; truncate(): NumberSchema; round(type: 'floor' | 'ceil' | 'trunc' | 'round'): NumberSchema; nullable(isNullable?: true): NumberSchema; nullable(isNullable: false): NumberSchema>; nullable(isNullable?: boolean): NumberSchema; required(message?: TestOptionsMessage): NumberSchema>; defined(): NumberSchema>; notRequired(): NumberSchema; oneOf( arrayOfValues: ReadonlyArray, message?: MixedLocale['oneOf'], ): NumberSchema>; equals( arrayOfValues: ReadonlyArray, message?: MixedLocale['oneOf'], ): NumberSchema>; test(name: string, message: TestOptionsMessage, test: TestFunction): this; test(name: string, message: TestOptionsMessage, test: AssertingTestFunction): NumberSchema; test(options: AssertingTestOptions>): NumberSchema; test(options: TestOptions>): this; optional(): NumberSchema; } export interface BooleanSchemaConstructor { (): BooleanSchema; new (): BooleanSchema; } export interface BooleanSchema extends Schema { nullable(isNullable?: true): BooleanSchema; nullable(isNullable: false): BooleanSchema>; nullable(isNullable?: boolean): BooleanSchema; required(message?: TestOptionsMessage): BooleanSchema>; defined(): BooleanSchema>; notRequired(): BooleanSchema; oneOf( arrayOfValues: ReadonlyArray, message?: MixedLocale['oneOf'], ): BooleanSchema>; equals( arrayOfValues: ReadonlyArray, message?: MixedLocale['oneOf'], ): BooleanSchema>; test(name: string, message: TestOptionsMessage, test: TestFunction): this; test(name: string, message: TestOptionsMessage, test: AssertingTestFunction): BooleanSchema; test(options: AssertingTestOptions>): BooleanSchema; test(options: TestOptions>): this; optional(): BooleanSchema; } export interface DateSchemaConstructor { (): DateSchema; new (): DateSchema; } export interface DateSchema extends Schema { min(limit: Date | string | Ref, message?: DateLocale['min']): DateSchema; max(limit: Date | string | Ref, message?: DateLocale['max']): DateSchema; nullable(isNullable?: true): DateSchema; nullable(isNullable: false): DateSchema>; nullable(isNullable?: boolean): DateSchema; required(message?: TestOptionsMessage): DateSchema>; defined(): DateSchema>; notRequired(): DateSchema; oneOf( arrayOfValues: ReadonlyArray, message?: MixedLocale['oneOf'], ): DateSchema>; equals( arrayOfValues: ReadonlyArray, message?: MixedLocale['oneOf'], ): DateSchema>; test(name: string, message: TestOptionsMessage, test: TestFunction): this; test(name: string, message: TestOptionsMessage, test: AssertingTestFunction): DateSchema; test(options: AssertingTestOptions>): DateSchema; test(options: TestOptions>): this; optional(): DateSchema; } export interface ArraySchemaConstructor { (schema?: Schema): NotRequiredArraySchema; new (): NotRequiredArraySchema<{}>; } export interface BasicArraySchema extends Schema { min(limit: number | Ref, message?: ArrayLocale['min']): this; max(limit: number | Ref, message?: ArrayLocale['max']): this; ensure(): this; compact( rejector?: (value: InferredArrayType, index: number, array: Array>) => boolean, ): this; // This doesn't narrow the type of the schema like the more primitive oneOf calls // it would be very complex to do that accurately with the subtypes, and it's not // really worth it because the oneOf check is a shallow (==) comparison so it rarely // applies to arrays anyway. oneOf(arrayOfValues: ReadonlyArray, message?: MixedLocale['oneOf']): this; equals(arrayOfValues: ReadonlyArray, message?: MixedLocale['oneOf']): this; test(name: string, message: TestOptionsMessage, test: TestFunction): this; test(options: TestOptions>): this; innerType: Schema; } export interface NotRequiredNullableArraySchema extends BasicArraySchema { of(type: Schema): NotRequiredNullableArraySchema; nullable(isNullable?: true): NotRequiredNullableArraySchema; nullable(isNullable: false): NotRequiredArraySchema; nullable(isNullable?: boolean): ArraySchema; required(message?: TestOptionsMessage): ArraySchema; defined(): NullableArraySchema; notRequired(): NotRequiredNullableArraySchema; optional(): NotRequiredNullableArraySchema; } export interface NullableArraySchema extends BasicArraySchema { of(type: Schema): NullableArraySchema; nullable(isNullable?: true): NullableArraySchema; nullable(isNullable: false): ArraySchema; nullable(isNullable?: boolean): ArraySchema; required(message?: TestOptionsMessage): ArraySchema; defined(): NullableArraySchema; notRequired(): NotRequiredNullableArraySchema; optional(): NotRequiredNullableArraySchema; } export interface NotRequiredArraySchema extends BasicArraySchema { of(type: Schema): NotRequiredArraySchema; nullable(isNullable?: true): NotRequiredNullableArraySchema; nullable(isNullable: false): NotRequiredArraySchema; nullable(isNullable: boolean): ArraySchema; required(message?: TestOptionsMessage): ArraySchema; defined(): ArraySchema; notRequired(): NotRequiredArraySchema; optional(): NotRequiredArraySchema; } export interface ArraySchema extends BasicArraySchema { of(type: Schema): ArraySchema; nullable(isNullable?: true): NullableArraySchema; nullable(isNullable: false | boolean): ArraySchema; required(message?: TestOptionsMessage): ArraySchema; defined(): ArraySchema; notRequired(): NotRequiredArraySchema; optional(): NotRequiredArraySchema; } export type ObjectSchemaDefinition = { // This shouldn't be necessary because MixedSchema extends Schema, but type // inference only works with it this way - otherwise when you use a mixed // field in object schema, it will type as `unknown`. Not sure why that is - // maybe some sort of inference depth limit? [field in keyof T]: Schema | MixedSchema | Ref; }; /** * Merges two interfaces. For properties in common, property types from `U` trump those of `T`. * This is conducive to the functionality of * [yup's `object.shape()` method](https://www.npmjs.com/package/yup#objectshapefields-object-nosortedges-arraystring-string-schema). */ export type Shape = | ({ [P in keyof T]: P extends keyof U ? U[P] : T[P] } & U) | PreserveOptionals; export interface ObjectSchemaConstructor { (fields?: ObjectSchemaDefinition): ObjectSchema; new (): ObjectSchema<{}>; } export interface ObjectSchema extends Schema { fields: { [k in keyof T]: Schema; }; shape( fields: ObjectSchemaDefinition, noSortEdges?: Array<[string, string]>, ): ObjectSchema>; from(fromKey: string, toKey: string, alias?: boolean): ObjectSchema; noUnknown(onlyKnownKeys?: boolean, message?: ObjectLocale['noUnknown']): ObjectSchema; unknown(allow?: boolean, message?: ObjectLocale['noUnknown']): ObjectSchema; transformKeys(callback: (key: any) => any): void; camelCase(): ObjectSchema; snakeCase(): ObjectSchema; constantCase(): ObjectSchema; nullable(isNullable?: true): ObjectSchema; nullable(isNullable: false): ObjectSchema>; nullable(isNullable?: boolean): ObjectSchema; required(message?: TestOptionsMessage): ObjectSchema>; defined(): ObjectSchema>; notRequired(): ObjectSchema; optional(): ObjectSchema; concat(schema: this): this; concat(schema: ObjectSchema): ObjectSchema; oneOf(arrayOfValues: ReadonlyArray, message?: MixedLocale['oneOf']): ObjectSchema; equals(arrayOfValues: ReadonlyArray, message?: MixedLocale['oneOf']): ObjectSchema; test(name: string, message: TestOptionsMessage, test: TestFunction): this; test(name: string, message: TestOptionsMessage, test: AssertingTestFunction): ObjectSchema; test(options: AssertingTestOptions>): ObjectSchema; test(options: TestOptions>): this; } export type TestFunction = ( this: TestContext, value: T, ) => boolean | ValidationError | Promise; export type AssertingTestFunction = (this: TestContext, value: any) => value is T; export type TransformFunction = (this: T, value: any, originalValue: any) => any; export interface WhenOptionsBuilderFunction { (value: any, schema: T): T; (v1: any, v2: any, schema: T): T; (v1: any, v2: any, v3: any, schema: T): T; (v1: any, v2: any, v3: any, v4: any, schema: T): T; } export type WhenOptionsBuilderObjectIs = ((...values: any[]) => boolean) | boolean | number | null | object | string; export type WhenOptionsBuilderObject = | { is: WhenOptionsBuilderObjectIs; then: any; otherwise: any; } | object; export type WhenOptions = WhenOptionsBuilderFunction | WhenOptionsBuilderObject; export interface TestContext { path: string; options: ValidateOptions; parent: any; schema: Schema; resolve: (value: any) => any; createError: (params?: { path?: string; message?: string; params?: object }) => ValidationError; } export interface ValidateOptions { /** * Only validate the input, and skip and coercion or transformation. Default - false */ strict?: boolean; /** * Return from validation methods on the first error rather than after all validations run. Default - true */ abortEarly?: boolean; /** * Remove unspecified keys from objects. Default - false */ stripUnknown?: boolean; /** * When false validations will not descend into nested schema (relevant for objects or arrays). Default - true */ recursive?: boolean; /** * Any context needed for validating schema conditions (see: when()) */ context?: object; } export interface TestMessageParams { path: string; value: any; originalValue: any; label: string; } interface BaseTestOptions

> { /** * Unique name identifying the test. Required for exclusive tests. */ name?: string; /** * Test function, determines schema validity */ test: TestFunction; /** * The validation error message */ message?: TestOptionsMessage

; /** * Values passed to message for interpolation */ params?: P; /** * Mark the test as exclusive, meaning only one of the same can be active at once */ exclusive?: boolean; } interface NonExclusiveTestOptions

> extends BaseTestOptions

{ exclusive?: false; } interface ExclusiveTestOptions

> extends BaseTestOptions

{ exclusive: true; name: string; } interface NonExclusiveAssertingTestOptions> extends NonExclusiveTestOptions

{ test: AssertingTestFunction; } interface ExclusiveAssertingTestOptions> extends ExclusiveTestOptions

{ test: AssertingTestFunction; } export type TestOptions

= {}> = NonExclusiveTestOptions

| ExclusiveTestOptions

; export type AssertingTestOptions = {}> = | NonExclusiveAssertingTestOptions | ExclusiveAssertingTestOptions; export interface SchemaFieldRefDescription { type: 'ref'; key: string; } export interface SchemaFieldInnerTypeDescription extends Pick> { innerType?: SchemaFieldDescription; } export type SchemaFieldDescription = SchemaDescription | SchemaFieldRefDescription | SchemaFieldInnerTypeDescription; export interface SchemaDescription { type: string; label: string; meta: object; tests: Array<{ name: string; params: { [k: string]: any } }>; fields: Record; } // ValidationError works a lot more like a class vs. a constructor // function that returns an interface. It's also got a couple of // static methods and it inherits from the generic Error class in // the [yup codebase][1]. // [1]: (https://github.com/jquense/yup/blob/master/src/ValidationError.js) export class ValidationError extends Error { name: string; message: string; value: any; /** * A string, indicating where there error was thrown. path is empty at the root level. */ path: string; type: any; /** * array of error messages */ errors: string[]; /** * In the case of aggregate errors, inner is an array of ValidationErrors throw earlier in the validation chain. */ inner: ValidationError[]; params?: object; static isError(err: any): err is ValidationError; static formatError(message: string | ((params?: any) => string), params?: any): string | ((params?: any) => string); constructor(errors: string | string[], value: any, path: string, type?: any); } // It is tempting to declare `Ref` very simply, but there are problems with these approaches: // // * `type Ref = Record;` - This is essentially how it was originally declared, but // just about any object satisfies this contract, which makes the type declaration too loose to // be useful. // // * `type Ref = object;` - This is a variation on the previous bullet in that it is too loose. // // * `class Ref {}` - This is yet another variation that is too loose. // // * `type Ref = void;` - This works and the emitted JavaScript is just fine, but it results in some // confusing IntelliSense, e.g it looks like the `ref()` returns `void`, which is not the case. // // The solution is twofold. 1.) Declare it as a class with a private constructor to prevent it from // being instantiated by anything but the `ref()` factory function, and; 2.) declare a private // readonly property (that yup actually places on the prototype) to force it to be structurally // incompatible with any other object type. /** * `Ref` is an opaque type that is internal to yup. Creating a `Ref` instance is accomplished via the `ref()` factory * function. */ export class Ref { private constructor(); private readonly __isYupRef: true; } // tslint:disable-next-line:no-empty-interface export interface Lazy extends Schema {} export interface FormatErrorParams { path: string; type: string; value?: any; originalValue?: any; } export type LocaleValue = string | ((params: FormatErrorParams) => string); export interface MixedLocale { default?: TestOptionsMessage; required?: TestOptionsMessage; oneOf?: TestOptionsMessage<{ values: any }>; notOneOf?: TestOptionsMessage<{ values: any }>; notType?: LocaleValue; } export interface StringLocale { length?: TestOptionsMessage<{ length: number }>; min?: TestOptionsMessage<{ min: number }>; max?: TestOptionsMessage<{ max: number }>; matches?: TestOptionsMessage<{ regex: RegExp }>; email?: TestOptionsMessage<{ regex: RegExp }>; url?: TestOptionsMessage<{ regex: RegExp }>; uuid?: TestOptionsMessage<{ regex: RegExp }>; trim?: TestOptionsMessage; lowercase?: TestOptionsMessage; uppercase?: TestOptionsMessage; } export interface NumberLocale { min?: TestOptionsMessage<{ min: number }>; max?: TestOptionsMessage<{ max: number }>; lessThan?: TestOptionsMessage<{ less: number }>; moreThan?: TestOptionsMessage<{ more: number }>; positive?: TestOptionsMessage<{ more: number }>; negative?: TestOptionsMessage<{ less: number }>; integer?: TestOptionsMessage; } export interface DateLocale { min?: TestOptionsMessage<{ min: Date | string }>; max?: TestOptionsMessage<{ max: Date | string }>; } export interface ObjectLocale { noUnknown?: TestOptionsMessage; } export interface ArrayLocale { min?: TestOptionsMessage<{ min: number }>; max?: TestOptionsMessage<{ max: number }>; } export interface LocaleObject { mixed?: MixedLocale; string?: StringLocale; number?: NumberLocale; date?: DateLocale; boolean?: {}; object?: ObjectLocale; array?: ArrayLocale; } export type InferType = T extends Schema ? InnerInferType

: never; // Shut off automatic exporting after this statement export {}; type KeyOfUndefined = { [P in keyof T]-?: undefined extends T[P] ? P : never; }[keyof T]; type PreserveNull = T extends null ? null : never; type PreserveUndefined = T extends undefined ? undefined : never; type PreserveOptionals = PreserveNull | PreserveUndefined; type Id = { [K in keyof T]: T[K] extends object ? InnerInferType : T[K]; }; type RequiredProps = Pick>>; type NotRequiredProps = Partial>>; type InnerInferType = | (T extends Array ? InnerInferTypeArray : Id & RequiredProps>) | PreserveOptionals; interface InnerInferTypeArray extends Array> {} type InferredArrayType = T extends Array ? U : T; /** If `T` is optional, returns optional `U`. */ type MaintainOptionality = T extends undefined ? U | undefined : U;