Closed MarcPorciuncula closed 1 year ago
Since Formik's submitted values are cast by Yup's cast function, we're also facing with that issue in our forms. Types in runtime and defined ones via TypeScript may differ. Some forms can not be submitted or get an unhandled error while submitting that is raised by Yup while casting.
And in this case, type source of Form is our ones not inferred by Yup. IMO, Yup is just a tool that we use for validation, developers should adjust type by their use case.
I have prepared a Codesandbox for this. It is in formik@2.4.0
by default.
Try to submit it when the version is 2.4.0
, you won't see the submitted alert because Yup will throw an error.
TypeError: The value of date could not be cast to a value that satisfies the schema type: "date".
attempted value:
result of cast: Invalid Date
Yup can not cast an empty string and throws an error, but if you downgrade the version to 2.2.9
, the code works as expected without any changes.
As you can see the type of date
input is defined as a string.
In version 2.4.0, if you submit it value changes into a Date object but is saved as a string in Formik's internal state.
What we expect was string because of our type definitions, and input handling.
But if we downgrade it, the string stays string.
I am also facing this issue where values of the field is a moment object.. however it's not submitting the form and throwing the above error, as its not able to perform moment.format() in the form.
had to revert it back to 2.2.9 from 2.40 to fix it.
Damn. Alright will roll this back.
First of all, big fan and long time user of Formik, thanks to the maintainers and contributors for all the hard work 🙏
Bug report
I was testing an upgrade to 2.4.0 at my org and came across what seemed like some strange behaviour. Turns out it was the introduction of Yup transforms support: https://github.com/jaredpalmer/formik/pull/3796
We use Formik + Yup + TypeScript and have been working with the assumption that even if the Yup schema might do transformations for the purposes of validation we will still receive the values of the original type in
onSubmit
. The TypeScript types of the package agree with this:However under 2.4.0 when using a Yup schema with transformations, the runtime types of
values
now disagree with TypeScript. Here's an example:This could have caused some real issues for us if it wasn't caught by our tests, as we would have values of the wrong type flowing from our forms into API calls etc. all unvalidated by TypeScript. I'm fairly confident we wouldn't be the only ones surprised by this.
I do believe https://github.com/jaredpalmer/formik/pull/3796 was a breaking change (there is a little discussion about that in the PR), and even if accepted as non-breaking the type mismatch mentioned above is a major issue for TS users.
Suggested solution(s)
The TypeScript types for onSubmit could be updated to use the Yup schema transformation type for values. But it seems like this would be non-trivial given
validationSchema
is typed pretty loosely at the moment, you would have to make it so the type ofonSubmit
changes depending on whether a Yup schema is provided.Users can work around this by manually casting the
values
received byonSubmit
toYup.TypeOf<typeof validationSchema>
, but imo that would be pretty clumsy/brittle. If you forget to do that then you'd get runtime behaviour that won't match your TypeScript.Additional context
We'll need to stay on 2.3.3 until some resolution is reached. It's too risky/too much work for us to upgrade as we would have to audit every Formik form across our codebase.
Your environment