Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Object or String type conditional with yup validation

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().

like image 733
mrks Avatar asked Feb 18 '26 20:02

mrks


1 Answers

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

like image 174
Vencovsky Avatar answered Feb 21 '26 14:02

Vencovsky