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

InferType inconsistent with module implementation #42360

Closed
4 tasks done
colinhacks opened this issue Feb 13, 2020 · 3 comments
Closed
4 tasks done

InferType inconsistent with module implementation #42360

colinhacks opened this issue Feb 13, 2020 · 3 comments

Comments

@colinhacks
Copy link

colinhacks commented Feb 13, 2020

If you know how to fix the issue, make a pull request instead.

If you do not mention the authors the issue will be ignored.


I have a suggestion for an improvement to the typings. Happy to submit a PR but I wanted to make sure this change makes sense first.

Currently, the yup package treats all object properties as optional by default:

const schema =  yup.object({
  asdf: yup.string()
})
schema.validate({})  // passes

Yet yup.InferType infers the type as: { asdf: string } when really it should be { asdf?: string }.

The idea behind this change is to make all calls to yup.string, yup.number, and yup.boolean optional by default, which aligns with the behavior of the actual package implementation. I have this working on my local machine, but I wanted to run this by you guys in case there's a reason it's currently done this way.

@mauricedb
Copy link
Contributor

mauricedb commented Feb 14, 2020

Interesting idea but I am pretty sure this would break a lot of code. I did consider doing this when inplementing InferType<T> but decided against it.

For one the inrerred type would change all of a sudden when users update to the newer versions of the type definition making this a large breaking change. By itself not a reason not to do so, if something is broken it should be fixed.

However the semantics of a required property in Yup is not the same as in TypeScript. For example a Yup.array().of(Yup.string()).required() will fail validation if you pass in an empty array. A required array should not be empty: empty arrays are also considered 'missing' values.

In general there isn't a one to one match between Yup and TypeScript concepts so this is never going to be perfect. Another example of that is a Yup.date() that will pass validation if you use the string "2020-02-14T07:52:25.495Z" if you don't call .strict()

@colinhacks
Copy link
Author

colinhacks commented Feb 21, 2020

Makes sense - thanks for your thoughtful reply. I understand your reasoning. Closing.

====================================

P.S. @mauricedb

Seems fairly easy to implement an yup.array().nonempty() method like this that makes that logic more explicit any provides a more accurate typing information.

export interface ArraySchema<T> extends BasicArraySchema<T[]> {
    //  ...
    nonempty(): NonEmptyArraySchema<T>
}

export interface NonEmptyArraySchema<T> extends Schema<[T, ...T[]]> {
  ...
}

@colinhacks
Copy link
Author

colinhacks commented Mar 8, 2020

For folks who stumble on this:

I ended up rolling my own validation library that's more rigorous when it comes to TS type inference: https://github.com/colinhacks/zod

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

2 participants