-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Chaining refinements which narrow down types gives them inconsistent runtime/static types #1598
Comments
Whoa, for a second I was also pretty confused about this @DanielBreiner. There's a feature that will let you abort early but you will have to use const userSchema = z
.object({
type: z.literal("Staff"),
age: z.number(),
})
.nullable()
.superRefine((user, ctx) => {
// Validation will halt here
if (!isNotNull(user)) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: "user shouldn't be null",
fatal: true,
});
}
})
.superRefine((user, ctx) => {
console.log(`superRefine: Is user null: ${user === null}`);
// If user is null, we get an exception here
if (user.age < 18) { // User is infered as possibly null here
ctx.addIssue({
code: z.ZodIssueCode.custom,
});
}
}); |
Yes, refine<RefinedOutput extends Output>(
check: (arg: Output) => arg is RefinedOutput,
message?: /* ... */
): ZodEffects<this, RefinedOutput, RefinedOutput>;
superRefine: (
refinement: RefinementEffect<Output>["refinement"]
) => ZodEffects<this, Output, Input>; |
@DanielBreiner you're right! The type parameters do not Actually re-reading your issue, do you mean you'd like |
It seems to me adding an option to abort on I do also think |
Alright, I did some cleaning up and split this issue into three: To me, the most apparent fixes to this issue are:
1 seems easier but leads to incorrect types. I do not know how difficult 2 would be or if it is even doable. Would love to hear other opinions on this. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Validation continues after an unsuccessful refine(), which gives it an incorrect return type and can make subsequent effects unexpectedly throw.
Code:
Output:
Expected output (last line):
Yes, there is an easy workaround by adding an
if (user !== null) return;
(which I have used for now). But the exception comes out of nowhere and the runtime type is different from the static type (TS tells us user can't be null) which can be very confusing and make the issue hard to find.The text was updated successfully, but these errors were encountered: