Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How do I migrate to v1 #1906

Open
jquense opened this issue Feb 8, 2023 · 19 comments
Open

How do I migrate to v1 #1906

jquense opened this issue Feb 8, 2023 · 19 comments

Comments

@jquense
Copy link
Owner

jquense commented Feb 8, 2023

Please read through the releases: https://github.com/jquense/yup/releases which document the breaking changes in more detail but the tl;dr; here is the following:

Big additions

The tuple type, object omit, pick, partial and deepPartial better TS support, most consistent behavior and

Breaking Changes

Flat bundle

There is no distributed lib folder anymore everything is bundled into one file with rollup

Stricter when API

#1542

tl;dr; use functions for then/otherwise conditions. convert .when({ to: true, then: yup.string().required() }) to .when({ to: true, then: schema => schema.required() })

Email validation is looser

Email validation via a regexp is impossible to do 100% correctly rather than try to match every case yup now matches the WHATWG definition of a valid email address to align with how browsers validate (or are supposed to validate) email inputs since that is a common use case.

We are not accepting changes to this at this time. If the built in validation is not sufficient for your use-case (totally reasonable!) please implement a regex or logic that you prefer, either with a custom method, or override the string email method via addMethod

Nullability and optionality are stricter and enforced during cast

This is the largest, and likely most disruptive change. Prior yup allowed for patterns like:

const nullableRequiredString = string().nullable().required()

nullableRequiredString.cast(null) // -> null

nullableRequiredString.validate(null) // ValidationError("this is required and cannot be null")

This may seem unintuitive behavior (and it is) but allowed for a common client side validation case, where we want to use a single schema to parse server data, as well as validate user input. In other words, a server might return invalid "default" values that should still fail when trying to submit.

Now, nullable(), defined and required are all mutually dependent methods. Meaning string().nullable().defined().required() produces a schema where the value must be a string, and not null or undefined. The effect of this is that the type of a cast() is now accurate and the same as the type returned from validate.

There is a migration path for folks who use this pattern: name.cast(null, { assert: 'ignore-optionality'}) // => null read more here

There are some knock-on changes caused by this as well, due to internals changing. Specifically describe() now returns optional and nullable properties instead of required to distinguish between the two possible states clearly. There is also no longer a test name required for most schema:

-const isRequired = schema.describe().tests.some(test => test.name === 'required')
+const description = schema.describe()
+const isRequired = !description.optional && !description.nullable

TS generics are faster, more accurate and very different from v032.

SchemaOf<Person> has been removed, and you can now provide the type you want the schema to match: ObjectSchema<Person>. read more: here

@frck006
Copy link

frck006 commented Feb 17, 2023

Hi,

I found nothing about 'BaseSchema' from 'yup', it disapears in v1 ? We can replace it by something else ?

Ok, I found "Schema" instead of "BaseSchema", are you agree ?

Regards,

@jquense
Copy link
Owner Author

jquense commented Feb 17, 2023

Yes it's just Schema now

@anonmily
Copy link

Hi,

We've switched to yup v1, and it seems to have broken the type imports since lib doesn't exist any longer. For v1 how should we go about accessing the types like MessageParams and ConditionOptions? They seem to be in the yup index.d.ts file, but don't seem to be exported in the yup module, so I'm unsure about how to access the types with v1.

@jquense
Copy link
Owner Author

jquense commented Mar 1, 2023

If you need more types exported open an issue (or better a PR)

@gajus
Copy link

gajus commented Mar 6, 2023

We previously had this code: Promise<AssertsShape<ObjectShape>>

What was AssertsShape updated to?

@erie-e9
Copy link

erie-e9 commented May 17, 2023

Hey guys, I was using import { RequiredStringSchema } from 'yup/lib/string'; in my project, I just tried to upgrade yup package from "yup": "^0.32.9" to "yup": "^1.1.1", but I just realized that it no longer exists. Could you help to understand which one can replace it please?

@jquense
Copy link
Owner Author

jquense commented May 17, 2023

Just StringSchema, check the types for how the generics work

@ImraKocis
Copy link

Hi, i am updating my project, I was using import { AnyObjectSchema, SchemaOf } from 'yup'. With what i have to replace SchemaOf to keep same logic in code.

@jquense
Copy link
Owner Author

jquense commented Jul 11, 2023

@ImraKocis that is answered in the last section of the first message

@csantos-nydig
Copy link

Hi @jquense - could you point me to what is the replacement for TypeOf?

I saw #1914 but I couldn't quite understand the migration step there

Thanks

@jquense
Copy link
Owner Author

jquense commented Jul 14, 2023

It's InferType

@csantos-nydig
Copy link

It's InferType

sorry I still don't understand: InferType returns T['__outputType'], TypeOf used to return T['__inputType']

@jquense
Copy link
Owner Author

jquense commented Jul 15, 2023

__inputType doesn't exist anymore, the concept was removed. It's explained a little more in depthin the the issue you linked

@csantos-nydig
Copy link

Could you please add #2058 (comment) to this migration guide? Thanks

0livare added a commit to 0livare/zod that referenced this issue Jul 21, 2023
So update Yup's section of the Zod comparison accordingly.

See: jquense/yup#1906
colinhacks pushed a commit to colinhacks/zod that referenced this issue Jul 30, 2023
)

So update Yup's section of the Zod comparison accordingly.

See: jquense/yup#1906
@adi-code
Copy link

adi-code commented Aug 25, 2023

Hi, I was extending DateSchema and allowing Reference<Date> as a param, imported from import Reference from 'yup/lib/Reference';. How can I import Reference in v1?

--EDIT--
I just noticed #2091 , keeping my fingers crossed for merging :-)
By the time workaround is available:

import * as yup from 'yup';
export type Reference<TValue = unknown> = ReturnType<(typeof yup.ref<TValue>)>;

source: https://stackoverflow.com/questions/76881812/yup-typing-a-retrieved-field-schema-from-an-object-schema/76903812#76903812

@phun-ky
Copy link

phun-ky commented Jan 19, 2024

How do I migrate when then and otherwise is a schema?

const steppedDurationSchema = object().shape({
  initialDuration: string().required(REQUIRED),
  subsequentStepsDuration: string().required(REQUIRED),
  maximumDuration: string(),
  stepUnit: string().required(REQUIRED)
});
const optionalSteppedDurationSchema = object().shape({
  initialDuration: string().nullable(),
  subsequentStepsDuration: string().nullable(),
  maximumDuration: string().nullable(),
  stepUnit: string().nullable()
});


steppedDuration: object().when(['usageEnds', 'endOfTripDurationType'], {
    is: (usageEnds: UsageEnd[], endOfTripDurationType?: string) =>
      usageEnds.includes(UsageEnd.STANDARD_DURATION) &&
      endOfTripDurationType === 'STEPPED_DURATION',
    then: steppedDurationSchema,
    otherwise: optionalSteppedDurationSchema
  })

@phun-ky
Copy link

phun-ky commented Jan 19, 2024

Solved, I had to move the definitions to inline..


steppedDuration: object().when(['usageEnds', 'endOfTripDurationType'], {
    is: (usageEnds: UsageEnd[], endOfTripDurationType?: string) =>
      usageEnds.includes(UsageEnd.STANDARD_DURATION) &&
      endOfTripDurationType === 'STEPPED_DURATION',
    then: (schema) =>
      schema.shape({
        initialDuration: string().required(REQUIRED),
        subsequentStepsDuration: string().required(REQUIRED),
        maximumDuration: string(),
        stepUnit: string().required(REQUIRED)
      }),
    otherwise: (schema) =>
      schema.shape({
        initialDuration: string().nullable(),
        subsequentStepsDuration: string().nullable(),
        maximumDuration: string().nullable(),
        stepUnit: string().nullable()
      })
  })

@sergei-lobanov
Copy link

Is there a plan to prepare normal migration document, with the list of all deprecated items and what should be updated.

@Sinled
Copy link

Sinled commented Apr 16, 2024

How do you migrate mixed.when ? Can't find any examples. In my code i have several places like this

export const ValidationSchema = object().shape({
    field: mixed().when('something', {
        is: false,
        then: string().label('Field').required(),
    }),
});

I've migrated places with string().when and number().when but it is unclear what to do with mixed.

is it ok to just replace

then: string().label('Field').required(),

with

then: () => string().label('Field').required(),

?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests