I don't use typescript very often so i'd be hard to keep any type defs up to date, but I'd be open to a PR adding them.
I made an attempt to add types but gave up after about 30 min. Would be good to find another builder pattern library鈥檚 type def for reference
Yeah I was wondering if joi had decent types TS, or flow. I might check
It does. Just looked.
https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/joi
Here's what I made so far, its gets the job done for me
declare var yup: yup.Yup;
declare module 'yup' {
export = yup;
}
declare namespace yup {
interface Yup {
reach<T extends YupBase<T>>(schema: T, path: string, value?: object, context?: object): T;
addMethod<T extends YupBase<T>>(schemaType: T, name: string, method: () => T): void;
ref(path: string, options: { contextPrefix: string }): Ref;
lazy<T extends YupBase<T>>(fn: (value: any) => T): Lazy;
ValidationError(errors: string | Array<string>, value: any, path: string);
mixed(): YupMixed;
string(): YupString;
object(): YupObject;
}
interface YupMixed extends YupBase<YupMixed>{
}
interface YupBase<T extends YupBase<T>>{
clone(): T;
label(label: string): T;
meta(metadata: object): T;
describe(): SchemaDescription;
concat(schema: T);
validate<U>(value: U, options?: object): Promise<ValidationError|U>;
validate<U>(value: U, options?: object, callback?: (value?: U, error?: ValidationError ) => any): void;
isValid(value: any, options?: object, callback?: () => any): Promise<boolean>;
cast(value: any): any;
isType(value: any): boolean;
strict(isStrict?: boolean): T;
strip(stripField?: boolean): T;
withMutation(builder: (current: T) => void): void;
default(value: any): T;
default(): Any;
nullable(isNullable?: boolean): T;
required(message?: string): T;
typeError(message: string): T;
oneOf(arrayOfValues: Array<any>, message?: string): T;
notOneOf(arrayOfValues: Array<any>, message?: string);
when(keys: string | Array<string>, builder: object |
((value, schema: T) => T) |
((v1, v2, schema: T) => T) |
((v1, v2, v3, schema: T) => T)|
((v1, v2, v3, v4, schema: T) => T)): T;
test(name: string, message: string, test: () => any, callbackStyleAsync?: boolean): T;
test(options: object): T;
transform(fn: (currentValue: any, originalValue: any) => any): T;
}
interface YupString extends YupBase<YupString> {
required(message?: string): YupString;
min(limit: number | Ref, message?: string): YupString;
max(limit: number | Ref, message?: string): YupString;
matches(regex: RegExp, message?: string): YupString;
email(message?: string): YupString;
url(message?: string): YupString;
ensure(): YupString;
trim(message?: string): YupString;
lowercase(message: string): YupString;
uppercase(message: string): YupString;
}
interface YupObject extends YupBase<YupObject> {
shape(fields: object, noSortEdges?: Array<[string, string]>): YupObject;
from(fromKey: string, toKey: string, alias: boolean): YupObject;
noUnknown(onlyKnownKeys: boolean, message?: string): YupObject;
camelCase(): YupObject;
constantCase(): YupObject;
}
interface SchemaDescription {
}
interface Ref {
}
interface Lazy {
}
interface ValidationError {
path: string;
value: any;
type: any;
errors: Array<string>;
inner: Array<ValidationError>;
}
interface Any {
}
}
This is what I came up with:
declare const yup: Yup;
declare module "yup" {
export = yup;
}
interface Yup {
reach(schema: Schema, path: string, value?: any, context?: any): Schema;
addMethod(schemaType: Schema, name: string, method: () => Schema): void;
ref(path: string, options: { contextPrefix: string }): Ref;
lazy(fn: (value: any) => Schema): Lazy;
mixed(): Schema;
string(): StringSchema;
number(): NumberSchema;
boolean(): BooleanSchema;
date(): DateSchema;
array(): ArraySchema;
object(): ObjectSchema;
}
interface ValidationError {
errors: string | Array<string>;
value: any;
path: string;
inner?: Array<ValidationError>;
}
interface Ref {
}
interface Lazy {
}
interface Schema {
clone(): Schema;
label(label: string): Schema;
meta(metadata: any): Schema;
describe(): SchemaDescription;
concat(schema: Schema): Schema;
validate(value: any, options?: ValidateOptions, callback?: () => void): Promise<any>;
isValid(value: any, options?: any, callback?: () => void): Promise<any>;
cast(value: any): any;
isType(value: any): boolean;
strict(isStrict: boolean): Schema;
strip(stripField: boolean): Schema;
withMutation(builder: (current: Schema) => void): void;
default(value: any): Schema;
default(): any;
nullable(isNullable: boolean): Schema;
required(message?: string): Schema;
typeError(message?: string): Schema;
oneOf(arrayOfValues: Array<any>, message?: string): Schema;
equals(arrayOfValues: Array<any>, message?: string): Schema;
notOneOf(arrayOfValues: Array<any>, message?: string): Schema;
when(keys: string | Array<string>, builder: any | ((value: any, schema: Schema) => Schema)): Schema;
test(name: string, message: string, test: Function, callbackStyleAsync?: boolean): Schema;
test(options: any): Schema;
transform(transformation: (currentValue: any, originalValue: any) => any): Schema;
}
interface StringSchema extends Schema {
required(message?: string): StringSchema;
min(limit: number | Ref, message?: string): StringSchema;
max(limit: number | Ref, message?: string): StringSchema;
matches(regex: RegExp, message?: string): StringSchema;
email(message?: string): StringSchema;
url(message?: string): StringSchema;
ensure(): StringSchema;
trim(message?: string): StringSchema;
lowercase(message?: string): StringSchema;
uppercase(message?: string): StringSchema;
}
interface NumberSchema extends Schema {
min(limit: number | Ref, message?: string): NumberSchema;
max(limit: number | Ref, message?: string): NumberSchema;
positive(message?: string): NumberSchema;
negative(message?: string): NumberSchema;
integer(message?: string): NumberSchema;
truncate(): NumberSchema;
round(type: "floor" | "ceil" | "trunc" | "round"): NumberSchema;
}
interface BooleanSchema extends Schema {
}
interface DateSchema extends Schema {
min(limit: Date | string | Ref, message?: string): DateSchema;
max(limit: Date | string | Ref, message?: string): DateSchema;
}
interface ArraySchema extends Schema {
of(type: Schema): ArraySchema;
required(message?: string): ArraySchema;
min(limit: number | Ref, message?: string): ArraySchema;
max(limit: number | Ref, message?: string): ArraySchema;
ensure(): ArraySchema;
compact(rejector: (value: any) => boolean): ArraySchema;
}
interface ObjectSchema extends Schema {
shape(fields: any, noSortEdges?: Array<[string, string]>): ObjectSchema;
from(fromKey: string, toKey: string, alias: boolean): ObjectSchema;
noUnknown(onlyKnownKeys: boolean, message?: string): ObjectSchema;
camelCase(): ObjectSchema;
constantCase(): ObjectSchema;
}
interface ValidateOptions {
}
interface SchemaDescription {
type: string;
label: string;
meta: object;
tests: Array<string>;
}
It should cover all available API features.
I would suggest to bundle the typings with yup, see http://www.typescriptlang.org/docs/handbook/declaration-files/publishing.html
It looks good, why not publish to DefinitelyTyped?
Pull request #21857 Type definitions for Yup submitted to DefinitelyTyped
Pull Request to Add Type Definitions was merged.
You can get them here https://www.npmjs.com/package/@types/yup
npm install --save-dev @types/yup
Thanks to @vtserman for the typings! On the other hand, there are arguments to keep the typings and the project together. Whether they are separated, i.e. on DefinitelyTyped, or together, updates are always needed.
Is there any way to resolve Ref values using Yup in TypeScript? I can`t see resolve method in any provided TypeScript interface and it was useful in some cases like https://github.com/jquense/yup/issues/49 (for example if we want to provide synchronous validation of two connected mixed fields in scheme).
Just for the record, would love to see the typings officially maintained. Maybe not so difficult if the public surface area of this package is nice and stable. TS adoption doing quite well these days!
any update here?
Typings can be found in the DefinitelyTyped repo
I would add they are a bit wrong but generally good 馃憤
When I want to concat two objects with different values it throws a type error. Can someone help fixing the types?
const one = yup.object().shape({
one: yup.string(),
});
const two = yup.object().shape({
two: yup.string(),
});
export const oneAndTwo = one.concat(
two,
);
const two: yup.ObjectSchema<yup.Shape<{}, {
two: string;
}>>
Argument of type 'ObjectSchema<Shape<{}, { two: string; }>>' is not assignable to parameter of type 'ObjectSchema<Shape<{}, { one: string; }>>'.
Type 'Shape<{}, { two: string; }>' is not assignable to type 'Shape<{}, { one: string; }>'.
Property 'one' is missing in type 'Shape<{}, { two: string; }>' but required in type '{ one: string; }'.ts(2345)
Another problem is that the returned type is wrong.
const oneAndTwo: yup.ObjectSchema<yup.Shape<{}, {
one: string;
}>>
const one = yup.object().shape({
one: yup.string(),
});
const two = yup.object().shape({
one: yup.string(),
});
export const oneAndTwo = one.concat(
two,
);
or
const one = yup.object().shape({
one: yup.string(),
});
const two = yup.object().shape({
one: yup.string(),
two: yup.string(),
});
export const oneAndTwo = one.concat(
two,
);
How can i use Union Types ?
const catSchema = yup.object().shape({cat: yup.string() })
const dogSchema = yup.object().shape({dog: yup.number() })
type Cat = yup.InferType<typeof catSchema>
type Dog = yup.InferType<typeof dogSchema>
type animal = Cat | Dog
Instead of having the types maintained separately, is there any hope of converting the main repo here to TS instead of JS, so types are mainated automatically along with updates?
Most helpful comment
Instead of having the types maintained separately, is there any hope of converting the main repo here to TS instead of JS, so types are mainated automatically along with updates?