yup: Missing generics in create() methods
For example, see string.ts: https://github.com/jquense/yup/blob/3ca0ebf2c26716e089316e6938deecb291c7c5e7/src/string.ts#L26-L34
The generated string.d.ts
ends up with a signature of, which makes the generic impossible to constrain:
export declare function create(): StringSchema<string | undefined, Record<string, any>, string | undefined>;
The solution is to make the create()
function generic, e.g.:
export function create<
TType extends Maybe<string> = string | undefined,
TContext extends AnyObject = AnyObject,
TOut extends TType = TType
>() {
return new StringSchema<TType, TContext, TOut>();
}
Based on quickly skimming your codebase (I may have missed some), it looks like this applies to the following:
- https://github.com/jquense/yup/blob/3ca0ebf2c26716e089316e6938deecb291c7c5e7/src/Reference.ts#L13
- https://github.com/jquense/yup/blob/3ca0ebf2c26716e089316e6938deecb291c7c5e7/src/boolean.ts#L8
- https://github.com/jquense/yup/blob/3ca0ebf2c26716e089316e6938deecb291c7c5e7/src/date.ts#L16
- https://github.com/jquense/yup/blob/3ca0ebf2c26716e089316e6938deecb291c7c5e7/src/number.ts#L10
- https://github.com/jquense/yup/blob/3ca0ebf2c26716e089316e6938deecb291c7c5e7/src/string.ts#L26
I’m trying to upgrade from yup@0.27.0
+ @types/yup@0.26.22
to just yup@0.32.6
(without the DefinitelyTypes @types
definitions), but I can’t because your type definitions would require too much unsafe casting. If you don’t have time to fix this yourself, let me know and I’ll make a PR.
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 3
- Comments: 16 (15 by maintainers)
sure, if you want to ensure a schema matches an object you still can, but the signature is a bit different. Now you would do something like:
Hmm, I can’t reproduce that… this works for me:
With a new test file:
By the way, I don’t think you’re type checking your test files. I had to add
@types/jest
as a dev dependency, remove a line with a type error fromtest/types.ts
, and then finally runtsc --build tsconfig.json
fromtests
directory. On the bright side, my test snippet above compiles.Have you tried comparing your code against the DefinitelyTyped definitions? I know they’re a little bit out of date (v0.29 according to the comment at the top of file), but they handle generics properly. Another issue I noticed is your
ObjectShape
definition which usesRecord
: https://github.com/jquense/yup/blob/3ca0ebf2c26716e089316e6938deecb291c7c5e7/src/object.ts#L30-L33Whereas DefinitelyTyped uses
[field in keyof T]
to constrain the keys: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/e539b14e9b5c4359ffaa67edbb845998d4fe8e27/types/yup/index.d.ts#L354-L360The advantage of DefinitelyTyped’s version is that it allows stricter value typing like this:
This is a contrived example, but I use this a ton with a large codebase at work where I’m passing form values around between yup, Formik, and Redux. If I changed
LoginFormValues
to be aRecord
I would lose type safety, which is bad.Sure, here’s a few examples of how DefinitelyTyped’s version provides type safety:
Whereas using your types from
yup@0.32.6
(import and interface omitted):See how the DefinitelyTyped version makes sure that my validator type and value type (
LoginFormValues
) match? That’s a big deal because this is the entry point for user data into the rest of the app, so I need to be sure that my validations are correct to avoid e.g. crashing when persisting the data to my Redux store or making an API request with incorrect data.