-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Using .catch causes input type to become unknown #2852
Comments
I think the behavior you observe is intended - for example, if the input is "foo", the output will be What's your expectation? That const schema = z.
number()
.transform(x => (1 < x && x < 255) ? x : 1) |
Hello ! capacity: z
.number()
.min(0)
.max(10)
.catch(() => {
throw new MyCustomException(
"My custom exception message"
);
}) The input type specifies capacity?: unknow which is not what I would have expected in such a case. I specified clearly I want a number, so the catch method shouldn't change it. I think the catch method should never change the expected input type. As a workaround, I just cast the capacity field ZodType like this: capacity: z
.number()
.min(0)
.max(10)
.catch(() => {
throw new MyCustomException(
"My custom exception message"
);
}) as z.ZodType<number> Regards. |
Hello, But it is obvious in his schema he wants a number value, so this is not logical that the catch method overwrites it, to accept any type including undefined. Regards. |
No, the schema will output a number, but will gladly accept a non-numeric input and replace it with That |
You can't know what will be done inside the catch by the developers. And I'm talking about the input type, not the ouput. Using catch doesn't mean we want to accept anything, and however this is precisely what it does currently. So where is the utility to specify constraints like number() before the catch() if the catch overwrites the types given by all the constraints before it? The input type is supposed to indicate what is the type that the schema expects, not what the schema constraints can manage, especially when this is a method who just catches all exceptions and is not supposed to add constraints about the expected type. In my example, I don't care the developer knows the schema can manage anything, I just want he knows by the input type that a number is expected, that's all I want. The use of the catch shouldn't modify these requirement. So if you find this current behavior normal, in this case everything before the catch doesn't affect the input type, so it's sufficient to just use a catch with nothing before, and implement all the expected type logic inside it for the strict same result. :/ Imagine you write an API method which requires a parameter object and you want to generate an API documentation specifying the expected param format. The used type for the parameter is the input type of your zod schema, and the first thing your method does is to parse and validate the parameter. Do you find useful to read that in the expected parameter object every field is partial with unknown type? :/ |
Maybe that's not what you want your code to say, but it's what the Perhaps the
Citation? I think the design principle of "parse, don't validate" implies advertised input types should be exhaustive (even if a tad broad at times).
No, I think the best design is to not try to handle malformed input (though that might be untenable) |
As @rotu says, this is how
I almost see what @vtgn is saying and there are other cases where Zod's philosophy on input types has thrown people off (see the discussion here #1492). If you want the inferred input type to be |
This all makes sense, but how about the use case when you have an enum that instead of failing you want to just set to undefined? Something like The best I've come up with is |
That seems a convoluted use of z.enum(['a', 'b', 'c']).or(z.unknown().transform(x => undefined)) Still, there are two issues that you might want to handle:
|
TL;DR
I came across this very same unexpected behaviour when using I may understand the reasoning and philosophy behind why Anyway, good news is, it can be fairly easily implemented as the above one-liner.
resulting in a That's it! Happy coding! |
When using a .catch block the typescript input type of the schema becomes unknown.
Without catch
SchemaType is number
With catch
SchemaType is unknown
This seems to happen for all types string, number boolean etc
The text was updated successfully, but these errors were encountered: