UNPKG

19 kBTypeScriptView Raw
1// Type definitions for yup 0.26
2// Project: https://github.com/jquense/yup
3// Definitions by: Dominik Hardtke <https://github.com/dhardtke>,
4// Vladyslav Tserman <https://github.com/vtserman>,
5// Moreton Bay Regional Council <https://github.com/MoretonBayRC>,
6// Sindre Seppola <https://github.com/sseppola>
7// Yash Kulshrestha <https://github.com/YashdalfTheGray>
8// Vincent Pizzo <https://github.com/vincentjames501>
9// Robert Bullen <https://github.com/robertbullen>
10// Yusuke Sato <https://github.com/sat0yu>
11// Desmond Koh <https://github.com/deskoh>
12// Maurice de Beijer <https://github.com/mauricedb>
13// Kalley Powell <https://github.com/kalley>
14// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
15// TypeScript Version: 2.8
16
17export function reach<T>(schema: Schema<T>, path: string, value?: any, context?: any): Schema<T>;
18export function addMethod<T extends Schema<any>>(
19 schemaCtor: AnySchemaConstructor,
20 name: string,
21 method: (this: T, ...args: any[]) => T,
22): void;
23export function ref(path: string, options?: { contextPrefix: string }): Ref;
24export function lazy<T>(fn: (value: T) => Schema<T>): Lazy;
25export function setLocale(customLocale: LocaleObject): void;
26export function isSchema(obj: any): obj is Schema<any>;
27
28export const mixed: MixedSchemaConstructor;
29export const string: StringSchemaConstructor;
30export const number: NumberSchemaConstructor;
31export const boolean: BooleanSchemaConstructor;
32export const bool: BooleanSchemaConstructor;
33export const date: DateSchemaConstructor;
34export const array: ArraySchemaConstructor;
35export const object: ObjectSchemaConstructor;
36
37export type AnySchemaConstructor =
38 | MixedSchemaConstructor
39 | StringSchemaConstructor
40 | NumberSchemaConstructor
41 | BooleanSchemaConstructor
42 | DateSchemaConstructor
43 | ArraySchemaConstructor
44 | ObjectSchemaConstructor;
45
46export type TestOptionsMessage<Extra extends Record<string, any> = {}, R = any> =
47 | string
48 | ((params: Extra & Partial<TestMessageParams>) => R);
49
50export interface Schema<T> {
51 clone(): this;
52 label(label: string): this;
53 meta(metadata: any): this;
54 meta(): any;
55 describe(): SchemaDescription;
56 concat(schema: this): this;
57 validate(value: any, options?: ValidateOptions): Promise<T>;
58 validateSync(value: any, options?: ValidateOptions): T;
59 validateAt(path: string, value: T, options?: ValidateOptions): Promise<T>;
60 validateSyncAt(path: string, value: T, options?: ValidateOptions): T;
61 isValid(value: any, options?: any): Promise<boolean>;
62 isValidSync(value: any, options?: any): value is T;
63 cast(value?: any, options?: any): T;
64 isType(value: any): value is T;
65 strict(isStrict: boolean): this;
66 strip(strip: boolean): this;
67 withMutation(fn: (current: this) => void): void;
68 default(value: any): this;
69 default(): T;
70 typeError(message?: TestOptionsMessage): this;
71 oneOf(arrayOfValues: Array<T | Ref | null>, message?: MixedLocale['oneOf']): this;
72 notOneOf(arrayOfValues: any[], message?: MixedLocale['notOneOf']): this;
73 when(keys: string | any[], builder: WhenOptions<this>): this;
74 test(
75 name: string,
76 message: TestOptionsMessage,
77 test: (this: TestContext, value?: any) => boolean | ValidationError | Promise<boolean | ValidationError>,
78 callbackStyleAsync?: boolean,
79 ): this;
80 // tslint:disable-next-line:no-unnecessary-generics
81 test<P>(options: TestOptions<P>): this;
82 transform(fn: TransformFunction<this>): this;
83}
84
85export interface MixedSchemaConstructor {
86 // tslint:disable-next-line:no-unnecessary-generics
87 <T = any>(): MixedSchema<T>;
88 // tslint:disable-next-line:no-unnecessary-generics
89 new <T = any>(options?: { type?: string; [key: string]: any }): MixedSchema<T>;
90}
91
92export interface MixedSchema<T = any> extends Schema<T> {
93 nullable(isNullable?: true): MixedSchema<T | null>;
94 nullable(isNullable: false): MixedSchema<Exclude<T, null>>;
95 nullable(isNullable?: boolean): MixedSchema<T>;
96 required(message?: TestOptionsMessage): MixedSchema<Exclude<T, undefined>>;
97 notRequired(): MixedSchema<T | undefined>;
98 concat(schema: this): this;
99 concat<U>(schema: MixedSchema<U>): MixedSchema<T | U>;
100}
101
102export interface StringSchemaConstructor {
103 (): StringSchema;
104 new (): StringSchema;
105}
106
107export interface StringSchema<T extends string | null | undefined = string> extends Schema<T> {
108 length(limit: number | Ref, message?: StringLocale['length']): StringSchema<T>;
109 min(limit: number | Ref, message?: StringLocale['min']): StringSchema<T>;
110 max(limit: number | Ref, message?: StringLocale['max']): StringSchema<T>;
111 matches(
112 regex: RegExp,
113 messageOrOptions?:
114 | StringLocale['matches']
115 | { message?: StringLocale['matches']; excludeEmptyString?: boolean },
116 ): StringSchema<T>;
117 email(message?: StringLocale['email']): StringSchema<T>;
118 url(message?: StringLocale['url']): StringSchema<T>;
119 ensure(): StringSchema<T>;
120 trim(message?: StringLocale['trim']): StringSchema<T>;
121 lowercase(message?: StringLocale['lowercase']): StringSchema<T>;
122 uppercase(message?: StringLocale['uppercase']): StringSchema<T>;
123 nullable(isNullable?: true): StringSchema<T | null>;
124 nullable(isNullable: false): StringSchema<Exclude<T, null>>;
125 nullable(isNullable?: boolean): StringSchema<T>;
126 required(message?: TestOptionsMessage): StringSchema<Exclude<T, undefined>>;
127 notRequired(): StringSchema<T | undefined>;
128}
129
130export interface NumberSchemaConstructor {
131 (): NumberSchema;
132 new (): NumberSchema;
133}
134
135export interface NumberSchema<T extends number | null | undefined = number> extends Schema<T> {
136 min(limit: number | Ref, message?: NumberLocale['min']): NumberSchema<T>;
137 max(limit: number | Ref, message?: NumberLocale['max']): NumberSchema<T>;
138 lessThan(limit: number | Ref, message?: NumberLocale['lessThan']): NumberSchema<T>;
139 moreThan(limit: number | Ref, message?: NumberLocale['moreThan']): NumberSchema<T>;
140 positive(message?: NumberLocale['positive']): NumberSchema<T>;
141 negative(message?: NumberLocale['negative']): NumberSchema<T>;
142 integer(message?: NumberLocale['integer']): NumberSchema<T>;
143 truncate(): NumberSchema<T>;
144 round(type: 'floor' | 'ceil' | 'trunc' | 'round'): NumberSchema<T>;
145 nullable(isNullable?: true): NumberSchema<T | null>;
146 nullable(isNullable: false): NumberSchema<Exclude<T, null>>;
147 nullable(isNullable?: boolean): NumberSchema<T>;
148 required(message?: TestOptionsMessage): NumberSchema<Exclude<T, undefined>>;
149 notRequired(): NumberSchema<T | undefined>;
150}
151
152export interface BooleanSchemaConstructor {
153 (): BooleanSchema;
154 new (): BooleanSchema;
155}
156
157export interface BooleanSchema<T extends boolean | null | undefined = boolean> extends Schema<T> {
158 nullable(isNullable?: true): BooleanSchema<T | null>;
159 nullable(isNullable: false): BooleanSchema<Exclude<T, null>>;
160 nullable(isNullable?: boolean): BooleanSchema<T>;
161 required(message?: TestOptionsMessage): BooleanSchema<Exclude<T, undefined>>;
162 notRequired(): BooleanSchema<T | undefined>;
163}
164
165export interface DateSchemaConstructor {
166 (): DateSchema;
167 new (): DateSchema;
168}
169
170export interface DateSchema<T extends Date | null | undefined = Date> extends Schema<T> {
171 min(limit: Date | string | Ref, message?: DateLocale['min']): DateSchema<T>;
172 max(limit: Date | string | Ref, message?: DateLocale['max']): DateSchema<T>;
173 nullable(isNullable?: true): DateSchema<T | null>;
174 nullable(isNullable: false): DateSchema<Exclude<T, null>>;
175 nullable(isNullable?: boolean): DateSchema<T>;
176 required(message?: TestOptionsMessage): DateSchema<Exclude<T, undefined>>;
177 notRequired(): DateSchema<T | undefined>;
178}
179
180export interface ArraySchemaConstructor {
181 <T>(schema?: Schema<T>): ArraySchema<T>;
182 new (): ArraySchema<{}>;
183}
184
185interface BasicArraySchema<T extends any[] | null | undefined> extends Schema<T> {
186 min(limit: number | Ref, message?: ArrayLocale['min']): this;
187 max(limit: number | Ref, message?: ArrayLocale['max']): this;
188 ensure(): this;
189 compact(
190 rejector?: (value: InferredArrayType<T>, index: number, array: Array<InferredArrayType<T>>) => boolean,
191 ): this;
192}
193
194export interface NotRequiredNullableArraySchema<T> extends BasicArraySchema<T[] | null | undefined> {
195 of<U>(type: Schema<U>): NotRequiredNullableArraySchema<U>;
196 nullable(isNullable?: true): NotRequiredNullableArraySchema<T>;
197 nullable(isNullable: false): NotRequiredArraySchema<T>;
198 nullable(isNullable?: boolean): ArraySchema<T>;
199 required(message?: TestOptionsMessage): NullableArraySchema<T>;
200 notRequired(): NotRequiredNullableArraySchema<T>;
201}
202
203export interface NullableArraySchema<T> extends BasicArraySchema<T[] | null> {
204 of<U>(type: Schema<U>): NullableArraySchema<U>;
205 nullable(isNullable?: true): NullableArraySchema<T>;
206 nullable(isNullable: false): ArraySchema<T>;
207 nullable(isNullable?: boolean): ArraySchema<T>;
208 required(message?: TestOptionsMessage): NullableArraySchema<T>;
209 notRequired(): NotRequiredNullableArraySchema<T>;
210}
211
212export interface NotRequiredArraySchema<T> extends BasicArraySchema<T[] | undefined> {
213 of<U>(type: Schema<U>): NotRequiredArraySchema<U>;
214 nullable(isNullable?: true): NotRequiredNullableArraySchema<T>;
215 nullable(isNullable: false): NotRequiredArraySchema<T>;
216 nullable(isNullable: boolean): ArraySchema<T>;
217 required(message?: TestOptionsMessage): ArraySchema<T>;
218 notRequired(): NotRequiredArraySchema<T>;
219}
220
221export interface ArraySchema<T> extends BasicArraySchema<T[]> {
222 of<U>(type: Schema<U>): ArraySchema<U>;
223 nullable(isNullable?: true): NullableArraySchema<T>;
224 nullable(isNullable: false | boolean): ArraySchema<T>;
225 required(message?: TestOptionsMessage): ArraySchema<T>;
226 notRequired(): NotRequiredArraySchema<T>;
227}
228
229export type ObjectSchemaDefinition<T extends object | null | undefined> = {
230 [field in keyof T]: Schema<T[field]> | Ref;
231};
232
233/**
234 * Merges two interfaces. For properties in common, property types from `U` trump those of `T`.
235 * This is conducive to the functionality of
236 * [yup's `object.shape()` method](https://www.npmjs.com/package/yup#objectshapefields-object-nosortedges-arraystring-string-schema).
237 */
238export type Shape<T extends object | null | undefined, U extends object> = {
239 [P in keyof T]: P extends keyof U ? U[P] : T[P];
240} &
241 U;
242
243export interface ObjectSchemaConstructor {
244 <T extends object>(fields?: ObjectSchemaDefinition<T>): ObjectSchema<T>;
245 new (): ObjectSchema<{}>;
246}
247
248export interface ObjectSchema<T extends object | null | undefined = object> extends Schema<T> {
249 shape<U extends object>(
250 fields: ObjectSchemaDefinition<U>,
251 noSortEdges?: Array<[string, string]>,
252 ): ObjectSchema<Shape<T, U>>;
253 from(fromKey: string, toKey: string, alias?: boolean): ObjectSchema<T>;
254 noUnknown(onlyKnownKeys?: boolean, message?: ObjectLocale['noUnknown']): ObjectSchema<T>;
255 transformKeys(callback: (key: any) => any): void;
256 camelCase(): ObjectSchema<T>;
257 constantCase(): ObjectSchema<T>;
258 nullable(isNullable?: true): ObjectSchema<T | null>;
259 nullable(isNullable: false): ObjectSchema<Exclude<T, null>>;
260 nullable(isNullable?: boolean): ObjectSchema<T>;
261 required(message?: TestOptionsMessage): ObjectSchema<Exclude<T, undefined>>;
262 notRequired(): ObjectSchema<T | undefined>;
263 concat(schema: this): this;
264 concat<U extends object>(schema: ObjectSchema<U>): ObjectSchema<T & U>;
265}
266
267export type TransformFunction<T> = (this: T, value: any, originalValue: any) => any;
268
269export interface WhenOptionsBuilderFunction<T> {
270 (value: any, schema: T): T;
271 (v1: any, v2: any, schema: T): T;
272 (v1: any, v2: any, v3: any, schema: T): T;
273 (v1: any, v2: any, v3: any, v4: any, schema: T): T;
274}
275
276export type WhenOptionsBuilderObjectIs = ((...values: any[]) => boolean) | boolean | number | null | object | string;
277
278export type WhenOptionsBuilderObject =
279 | {
280 is: WhenOptionsBuilderObjectIs;
281 then: any;
282 otherwise: any;
283 }
284 | object;
285
286export type WhenOptions<T> = WhenOptionsBuilderFunction<T> | WhenOptionsBuilderObject;
287
288export interface TestContext {
289 path: string;
290 options: ValidateOptions;
291 parent: any;
292 schema: Schema<any>;
293 resolve: (value: any) => any;
294 createError: (params?: { path?: string; message?: string, params?: object }) => ValidationError;
295}
296
297export interface ValidateOptions {
298 /**
299 * Only validate the input, and skip and coercion or transformation. Default - false
300 */
301 strict?: boolean;
302 /**
303 * Teturn from validation methods on the first error rather than after all validations run. Default - true
304 */
305 abortEarly?: boolean;
306 /**
307 * Remove unspecified keys from objects. Default - false
308 */
309 stripUnknown?: boolean;
310 /**
311 * When false validations will not descend into nested schema (relevant for objects or arrays). Default - true
312 */
313 recursive?: boolean;
314 /**
315 * Any context needed for validating schema conditions (see: when())
316 */
317 context?: object;
318}
319
320export interface TestMessageParams {
321 path: string;
322 value: any;
323 originalValue: any;
324 label: string;
325}
326
327export interface TestOptions<P extends Record<string, any> = {}, R = any> {
328 /**
329 * Unique name identifying the test
330 */
331 name?: string;
332
333 /**
334 * Test function, determines schema validity
335 */
336 test: (this: TestContext, value: any) => boolean | ValidationError | Promise<boolean | ValidationError>;
337
338 /**
339 * The validation error message
340 */
341 message?: TestOptionsMessage<P, R>;
342
343 /**
344 * Values passed to message for interpolation
345 */
346 params?: P;
347
348 /**
349 * Mark the test as exclusive, meaning only one of the same can be active at once
350 */
351 exclusive?: boolean;
352}
353
354export interface SchemaDescription {
355 type: string;
356 label: string;
357 meta: object;
358 tests: Array<{ name: string; params: object }>;
359 fields: object;
360}
361
362// ValidationError works a lot more like a class vs. a constructor
363// function that returns an interface. It's also got a couple of
364// static methods and it inherits from the generic Error class in
365// the [yup codebase][1].
366// [1]: (https://github.com/jquense/yup/blob/master/src/ValidationError.js)
367export class ValidationError extends Error {
368 name: string;
369 message: string;
370 value: any;
371 /**
372 * A string, indicating where there error was thrown. path is empty at the root level.
373 */
374 path: string;
375 type: any;
376 /**
377 * array of error messages
378 */
379 errors: string[];
380
381 /**
382 * In the case of aggregate errors, inner is an array of ValidationErrors throw earlier in the validation chain.
383 */
384 inner: ValidationError[];
385 params?: object;
386
387 static isError(err: any): err is ValidationError;
388 static formatError(message: string | ((params?: any) => string), params?: any): string | ((params?: any) => string);
389
390 constructor(errors: string | string[], value: any, path: string, type?: any);
391}
392
393// It is tempting to declare `Ref` very simply, but there are problems with these approaches:
394//
395// * `type Ref = Record<string, any>;` - This is essentially how it was originally declared, but
396// just about any object satisfies this contract, which makes the type declaration too loose to
397// be useful.
398//
399// * `type Ref = object;` - This is a variation on the previous bullet in that it is too loose.
400//
401// * `class Ref {}` - This is yet another variation that is too loose.
402//
403// * `type Ref = void;` - This works and the emitted JavaScript is just fine, but it results in some
404// confusing IntelliSense, e.g it looks like the `ref()` returns `void`, which is not the case.
405//
406// The solution is twofold. 1.) Declare it as a class with a private constructor to prevent it from
407// being instantiated by anything but the `ref()` factory function, and; 2.) declare a private
408// readonly property (that yup actually places on the prototype) to force it to be structurally
409// incompatible with any other object type.
410
411/**
412 * `Ref` is an opaque type that is internal to yup. Creating a `Ref` instance is accomplished via the `ref()` factory
413 * function.
414 */
415export class Ref {
416 private constructor();
417 private readonly __isYupRef: true;
418}
419
420// tslint:disable-next-line:no-empty-interface
421export interface Lazy extends Schema<any> {}
422
423export interface FormatErrorParams {
424 path: string;
425 type: string;
426 value?: any;
427 originalValue?: any;
428}
429
430export type LocaleValue = string | ((params: FormatErrorParams) => string);
431
432interface MixedLocale {
433 default?: TestOptionsMessage;
434 required?: TestOptionsMessage;
435 oneOf?: TestOptionsMessage<{ values: any }>;
436 notOneOf?: TestOptionsMessage<{ values: any }>;
437 notType?: LocaleValue;
438}
439
440interface StringLocale {
441 length?: TestOptionsMessage<{ length: number }>;
442 min?: TestOptionsMessage<{ min: number }>;
443 max?: TestOptionsMessage<{ max: number }>;
444 matches?: TestOptionsMessage<{ regex: RegExp }>;
445 email?: TestOptionsMessage<{ regex: RegExp }>;
446 url?: TestOptionsMessage<{ regex: RegExp }>;
447 trim?: TestOptionsMessage;
448 lowercase?: TestOptionsMessage;
449 uppercase?: TestOptionsMessage;
450}
451
452interface NumberLocale {
453 min?: TestOptionsMessage<{ min: number }>;
454 max?: TestOptionsMessage<{ max: number }>;
455 lessThan?: TestOptionsMessage<{ less: number }>;
456 moreThan?: TestOptionsMessage<{ more: number }>;
457 positive?: TestOptionsMessage<{ more: number }>;
458 negative?: TestOptionsMessage<{ less: number }>;
459 integer?: TestOptionsMessage;
460}
461
462interface DateLocale {
463 min?: TestOptionsMessage<{ min: Date | string }>;
464 max?: TestOptionsMessage<{ max: Date | string }>;
465}
466
467interface ObjectLocale {
468 noUnknown?: TestOptionsMessage;
469}
470
471interface ArrayLocale {
472 min?: TestOptionsMessage<{ min: number }>;
473 max?: TestOptionsMessage<{ max: number }>;
474}
475
476export interface LocaleObject {
477 mixed?: MixedLocale;
478 string?: StringLocale;
479 number?: NumberLocale;
480 date?: DateLocale;
481 boolean?: {};
482 object?: ObjectLocale;
483 array?: ArrayLocale;
484}
485
486export type InferType<T> = T extends Schema<infer P> ? InnerInferType<P> : never;
487
488// Shut off automatic exporting after this statement
489export {};
490
491type KeyOfUndefined<T> = {
492 [P in keyof T]-?: undefined extends T[P] ? P : never;
493}[keyof T];
494
495type Id<T> = { [K in keyof T]: T[K] };
496type RequiredProps<T> = Pick<T, Exclude<keyof T, KeyOfUndefined<T>>>;
497type NotRequiredProps<T> = Partial<Pick<T, KeyOfUndefined<T>>>;
498type InnerInferType<T> = Id<NotRequiredProps<T> & RequiredProps<T>>;
499type InferredArrayType<T> = T extends Array<infer U> ? U : T;
500
\No newline at end of file