Search code examples
typescriptyup

Cannot make when condition working with Yup validation schema


I'm having some troubles creating a schema validation with a condition using Yup :

import {
  object, string, 
} from 'yup';

const formValidationSchema = () => object().shape({
  someInput: string().required('Some error Message'),
  someInput2: string().required('Some error Message 2'),
  someInput3: string().required('Some error Message 3'),
  someInput4: string().when('someInput2', {
    is: 'Some string value',
    then: string().optional(),
    otherwise: string().required('Some error Message 4'),
  }),
});

My IDE is complaining with the following error : TS2769: No overload matches this call.

It looks like it is trying to use this signature for the when method :

when(builder: ConditionBuilder<this>): this;

When it should be using this one :

when(keys: string | string[], options: ConditionConfig<this>): this;

I also tried using an arrow function in the is param since it is the line underlined by my IDE :

  // ... 
  someInput4: string().when('someInput2', {
    is: (someInput2) => someInput2 === 'Some string value',
    then: string().optional(),
    otherwise: string().required('Some error Message 4'),
  }),

No succes there neither.


Solution

  • According to yup package TypeScript code, this is the typing of ConditionConfig:

    type ConditionConfig<T extends ISchema<any>> = {
        is: any | ((...values: any[]) => boolean);
        then?: (schema: T) => ISchema<any>;
        otherwise?: (schema: T) => ISchema<any>;
    };
    

    Obviously as you can see your code does not match this type, because you don't provide a function on both then and otherwise keys.

    For example, if I just do this arbitrary code, I get no TypeScript error:

    import {
      object, string, number
    } from 'yup';
    
    const formValidationSchema = () => object().shape({
      someInput: string().required('Some error Message'),
      someInput2: string().required('Some error Message 2'),
      someInput3: string().required('Some error Message 3'),
      someInput4: number().when('isBig', {
      is: 'Some string value',
        then: (schema) => schema.min(5),
        otherwise: (schema) => schema.min(0),
      }),
    });