I am using yup in combination with Formik in my React application to validate a TypeScript model/interface.
We previously had a yup.object for the follwing schema:
export const InputSchema = yup.object({
id: yup.string(),
name: yup.string().required().min(MIN_DESC_LENGTH).max(_MAX_NAME_LENGTH),
description: yup.string().required().matches(/(?!^\d+$)^[\s\S]+$/, 'Please enter a valid description').min(MIN_DESC_LENGTH).max(_MAX_DESC_LENGTH),
contact: yup.string().required()
});
As we changed our interface now, name and description fields can either be a string or an object.
I still want to validate my form with yup, so I tried to use name: yup.mixed() and description: yup.mixed() but now I get obviously problems with the min.() and .matches() functions.
Is it possible to have a string OR object condition? So if it is a yup.string() then, min/max will be used, otherwise just yup.object().
I looked for a way to do this in a simple way but couldn't find any, but the solution they give is to use yup.lazy.
For your case it would be
Yup.object({
...
name: Yup.lazy(value => {
switch (typeof value) {
case 'object':
return Yup.object(); // schema for object
case 'string':
return Yup.string().min(MIN_DESC_LENGTH).max(_MAX_NAME_LENGTH); // schema for string
default:
return Yup.mixed(); // here you can decide what is the default
}
}),
...
})
Another way you can do is like this gist.
It creates a custom method with .addMethod that receives schemas and validates all. Pretty good approach
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With