zod
zod copied to clipboard
feat(#1690): Add `ZodRequired`
Closes #1690
This PR adds the ZodRequired
type, which removes any undefined
from both the schema's output and input.
~Note: I couldn't add
.required()
to the rootZodType
class because it conflicts with the.required()
method ofZodObject
. Suggestions are welcome. I feel like it should live in the rootZodType
class...~
Deploy Preview for guileless-rolypoly-866f8a ready!
Built without sensitive environment variables
Name | Link |
---|---|
Latest commit | 93b89968026404b2b2e4a5223b43f25705ce2681 |
Latest deploy log | https://app.netlify.com/sites/guileless-rolypoly-866f8a/deploys/63a50e1f2c78fd0009d94987 |
Deploy Preview | https://deploy-preview-1738--guileless-rolypoly-866f8a.netlify.app |
Preview on mobile | Toggle QR Code...Use your smartphone camera to open QR code link. |
To edit notification comments on pull requests, go to your Netlify site settings.
@santosmarco-caribou looks good at a glance!
I haven't taken an in depth look - but I wonder if, for the sake of keeping .required()
on the root ZodType
, it would be possible to bring in the specific ZodObject
funtionality at the top ZodType
so that there's no confilct in the namespace? or via a _required()
on the ZodObject with a instanceof
check at the ZodType
level? Just some ideas.
@santosmarco-caribou looks good at a glance!
I haven't taken an in depth look - but I wonder if, for the sake of keeping
.required()
on the rootZodType
, it would be possible to bring in the specificZodObject
funtionality at the topZodType
so that there's no confilct in the namespace? or via a_required()
on the ZodObject with ainstanceof
check at theZodType
level? Just some ideas.
I'm afraid it isn't possible to bring the ZodObject
logic up to the root ZodType
class since the return type depends on the schema
, unknownKeys
, and catchall
, which ZodType
does not have access to.
@MaxArturo
I came up with a solution using overloads. Don't know if that's the best way to handle this, but well, it works, passes all tests, and does not create any conflict.

Very neat! Good job @santosmarco . To be sure, it would be a good idea to add tests that flex the interaction of ZodObject
with .require()
specifically, I think we're missing those.
Very neat! Good job @santosmarco . To be sure, it would be a good idea to add tests that flex the interaction of
ZodObject
with.require()
specifically, I think we're missing those.
@maxArturo Thanks. I've added additional tests specifically for ZodObject
's .required()
and everything looks OK.
I've also updated the .required()
logic, return types, and removed deoptional
(no longer needed) :)
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.
On further reflection, I think Zod should possibly consider generalizing this to ZodExclude
. Though I'm still on the fence about whether this is a good idea.
Note that the types in this PR are technically wrong. For instance, if .required()
behaved as implemented in this PR, the following schema would have Output
type string
, when it should be string | undefined
.
z.string().transform(val => Math.random() > 0.5 ? val : undefined).required()
There's some inherent ambiguity here, which is why I've been hesistant to merge this. The open question is this: does the "required" check happen before or after the innerType
parsing? I think different people will have different expectations about how this should work, unfortunately.
I'm going to close this for now, but I'll keep this in mind over the development cycle for Zod 4. I need to do some restructuring and see if a more natural API emerges for making object schemas required (which is the fundamental issue solved by this PR). I also need to think more about how this will interact with Zod 4's new approach to exactOptionalPropertyTypes
. I'll re-open if I decide to go ahead with ZodRequired
. Thanks for the great work Marco 🙌