-
-
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
Feat/add guard #3862
base: main
Are you sure you want to change the base?
Feat/add guard #3862
Conversation
discussion: unlike check, guard is only visible when Output extend Input
✅ Deploy Preview for guileless-rolypoly-866f8a ready!Built without sensitive environment variables
To edit notification comments on pull requests, go to your Netlify site configuration. |
bc0ffd2
to
1afd010
Compare
Considering the guard(this: ZodType<Output>, data: unknown): data is Output;
guard(this: ZodType<Output, ZodTypeDef, Input>, data: unknown): data is Input;
guard(data: unknown): boolean {
return this.safeParse(data).success;
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool PR! I've done something similar in the past, so it's cool to see others have a similar use case.
I have a suggestion for this PR, and a recommendation that I thought you might find interesting.
Suggestion:
It might be worth exploring a solution that doesn't "crowd" existing behavior for users that don't care about this feature.
For example, adding a type parameter to all string schemas means all users will now see that type parameter everywhere they use z.string
in their schemas, which adds noise. It wouldn't break anything, but it does get pretty noisy, and could hurt the DX overall.
Recommendation
If this is something you're needing, here's a pattern you can use to extend any library's behavior. YMMV ofc, and I've found libraries that ship combinators (like zod) are especially good fits for this approach.
You'd probably want to use a class so you can extend the existing behavior, but in general I've found this approach to be more flexible than it might appear at first glance.
Edit: fixed a bug in the playground
Proposal: reintroducing type guard
Summary
This proposal seeks to reintroduce a type guard functionality to Zod, with a revised and safer implementation. AFAIK the removal of the legacy
check
method was prompted by the adoption of transformers, due to its potential disconnect betweenInput
andOutput
types. This new implementation, however, reintroduces a type guard with a strict condition: it is only available when theOutput
type extends theInput
type, ensuring the guard is actually correct.Why is this necessary?
Zod is a TypeScript-first schema validation library with robust static type inference. While the
safeParse
method in Zod provides runtime validation, it does not allow TypeScript to infer the type of data in the broader scope after validation.This new guard solves that limitation by ensuring that TypeScript can infer the type of the validated data at compile-time, making the development experience smoother and safer.
Proposed Implementation
zod/deno/lib/types.ts
Lines 521 to 526 in 47f04a9
Naming
As it has already been discussed in various issues, I also suggest to avoid overlap with the legacy
check
method and therefore use a fresh name for this implementation. My proposal usesguard
, which I think clearly conveys its purpose. An alternative name could beis
, ...?potentially resolves
.guard()
#2413Update:I just realised thecoerce
options do not have an impact on theInput
making this solution potentially incorrect.I changed the PR to DRAFT and am looking into this now. #2413 (comment)
Update:
AFAICT coercion should influence the Input type as well. To address this, I’ve adjusted the coercion implementations to ensure they impact Input, making the guards also work in those cases.
TODOs