Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Formik and yup validation on string type using latest release 0.29.3

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

like image 695
zaq Avatar asked Sep 15 '20 15:09

zaq


People also ask

Can I use Yup without Formik?

Yes, you can use Yup without Formik, and you can use Formik without Yup. However, if you're building a React application, form validation becomes much easier when you use a Formik component and Yup email validation together.


1 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.

like image 116
Vencovsky Avatar answered Oct 24 '22 05:10

Vencovsky