Formik and yup validation on string type using latest release 0.29.3

Viewed 6877

I have the following phone number validation using yup but I am getting TS error after upgrading

"yup": ^0.27.0 to "yup": "^0.29.3"

and

"@types/yup": "^0.26.27" to "@types/yup": "^0.29.7"

const ValidationSchema = Yup.object().shape<ICreateUserForm>({
  phone: Yup.string()
    .required("Required")
    .test("countryCode", "Must include country code", (phone?: string) => {
      return !!phone && phone.startsWith("+")
    })
    .test("isValidNumber", "Must be valid phonenumber", (phone?: string) => {
      const parsedNumber = !!phone && parsePhoneNumberFromString(phone)
      return parsedNumber && parsedNumber.isValid() ? true : false
    })
})

Error

No overload matches this call.
  Overload 1 of 4, '(name: string, message: TestOptionsMessage<{}, any>, test: TestFunction<string | null | undefined, object>): StringSchema<string, object>', gave the following error.
    Argument of type '(phone?: string | undefined) => boolean' is not assignable to parameter of type 'TestFunction<string | null | undefined, object>'.
      Types of parameters 'phone' and 'value' are incompatible.
        Type 'string | null | undefined' is not assignable to type 'string | undefined'.
          Type 'null' is not assignable to type 'string | undefined'.
  Overload 2 of 4, '(name: string, message: TestOptionsMessage<{}, any>, test: AssertingTestFunction<string, object>): StringSchema<string, object>', gave the following error.
    Argument of type '(phone?: string | undefined) => boolean' is not assignable to parameter of type 'AssertingTestFunction<string, object>'.
      Signature '(phone?: string | undefined): boolean' must be a type predicate.  TS2769

Following is the Type definition of phone

type AvailableLanguage = "fi" | "en"

export interface CreateUserForm {
  firstName: string
  lastName: string
  email: string
  phone: string
  language: AvailableLanguage
}

Since there are bo breaking changes in the recent changelog. I am not sure what has happened behind the scenes

https://github.com/jquense/yup/blob/master/CHANGELOG.md https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/yup

2 Answers

The problem is in how you declare the type of the argument in the function passed to .test.

You are passing (phone?: string) but it needs to be (phone?: string | null) as the error mentions.

Here is how it should work

const ValidationSchema = Yup.object().shape<ICreateUserForm>({
  phone: Yup.string()
    .required("Required")
    .test("countryCode", "Must include country code", (phone?: string | null) => {
      return !!phone && phone.startsWith("+")
    })
    .test("isValidNumber", "Must be valid phonenumber", (phone?: string | null) => {
      const parsedNumber = !!phone && parsePhoneNumberFromString(phone)
      return parsedNumber && parsedNumber.isValid() ? true : false
    })
})

I'm not sure if the property phone should allow undefined (using ?), but I think you can also pass it as a string only like (phone: string).

Maybe you are wondering:

Why I'm getting this typescript error after upgrading?

Probably because the old version didn't support typescript that good and in the new version they "fixed" or made something better with typescript.

I had a similar problem and solved it by installing the latest version of the Yup package and @types/yup packages.

npm i -S yup@0.32.8
npm i -D @ types/yup@0.29.11

I did a test on Repl.it: [https://repl.it/join/ytnxoyno-jefferson1919]

Related