Yup: Join 2 Variabls Schemas of Yup validations

Created on 15 Apr 2019  路  3Comments  路  Source: jquense/yup

I am looking to merge two different schema declarations in YUP. Below are the variables

const validationSchema = yup.object().shape({
  email: yup
    .string()
    .label('Email')
    .email()
    .required(),
  password: yup
    .string()
    .label('Password')
    .required()
    .min(2, 'Seems a bit short...')
    .max(10, 'We prefer insecure system, try a shorter password.')
});

const optionalValidationSchema = yup.object().shape({
  confirmPassword: yup
    .string()
    .required()
    .label('Confirm password')
    .test('passwords-match', 'Passwords must match ya fool', function(value) {
      return this.parent.password === value;
    }),
  agreeToTerms: yup
    .boolean()
    .label('Terms')
    .test(
      'is-true',
      'Must agree to terms to continue',
      value => value === true
    ),
});

const mergedSchema = {Merge above 2 here}

So I am looking to merge validationSchema and optionalValidationSchema This is needed because the first variable is the required validations i.e. those fields will always needed to be validated whereas optionalValidationSchema will be valid for only certain number of users. I tried concating object as well but that didn't helped. As validationSchema is validations that is always needed I do not want to redeclare these within optionalValidationSchema that is why I am looking for a way to concatenate them when needed

Here is my Formik declaration
<Formik validationSchema={ mergedSchema }

Most helpful comment

const merged = validationSchema.concat(optionalValidationSchema)

All 3 comments

const merged = validationSchema.concat(optionalValidationSchema)

Throws an error in typescript @jquense

No overload matches this call.
  Overload 1 of 2, '(schema: ObjectSchema<Shape<object | undefined, { email: string; password: string; }>, object>): ObjectSchema<Shape<object | undefined, { email: string; password: string; }>, object>', gave the following error.
    Argument of type 'ObjectSchema<Shape<object | undefined, { confirmPassword: string; agreeToTerms: boolean | undefined; }>, object>' is not assignable to parameter of type 'ObjectSchema<Shape<object | undefined, { email: string; password: string; }>, object>'.
      Types of property 'fields' are incompatible.
        Type '{ confirmPassword: Schema<string, object>; agreeToTerms: Schema<boolean | undefined, object>; } | undefined' is not assignable to type '{ email: Schema<string, object>; password: Schema<string, object>; } | undefined'.
          Type '{ confirmPassword: Schema<string, object>; agreeToTerms: Schema<boolean | undefined, object>; }' is missing the following properties from type '{ email: Schema<string, object>; password: Schema<string, object>; }': email, password
  Overload 2 of 2, '(schema: ObjectSchema<object, object>): ObjectSchema<object & { email: string; password: string; }, object>', gave the following error.
    Argument of type 'ObjectSchema<Shape<object | undefined, { confirmPassword: string; agreeToTerms: boolean | undefined; }>, object>' is not assignable to parameter of type 'ObjectSchema<object, object>'.
      Types of property 'fields' are incompatible.
        Type '{ confirmPassword: Schema<string, object>; agreeToTerms: Schema<boolean | undefined, object>; } | undefined' is not assignable to type 'object'.
          Type 'undefined' is not assignable to type 'object'.

Also, after a bit of experimentation, I spread the fields of validationSchema into optionalValidationSchema. I think logically it should be vice versa. However, it worked for me but I don't know if this is the right practice.

const validationSchema = yup.object().shape({
  email: yup.string().label('Email').email().required(),
  password: yup
    .string()
    .label('Password')
    .required()
    .min(2, 'Seems a bit short...')
    .max(10, 'We prefer insecure system, try a shorter password.'),
});

const optionalValidationSchema = yup.object().shape({
  confirmPassword: yup
    .string()
    .required()
    .label('Confirm password')
    .test('passwords-match', 'Passwords must match ya fool', function (value) {
      return this.parent.password === value;
    }),
  agreeToTerms: yup
    .boolean()
    .label('Terms')
    .test('is-true', 'Must agree to terms to continue', (value) => value === true),
  ...validationSchema.fields, // Spreading fields from one schema to another
});
Was this page helpful?
0 / 5 - 0 ratings

Related issues

haddyo picture haddyo  路  3Comments

cfteric picture cfteric  路  3Comments

odesey picture odesey  路  4Comments

the-daniel-rothig picture the-daniel-rothig  路  4Comments

you-fail-me picture you-fail-me  路  4Comments