Schema introspection of optional or required fields
See original GitHub issueHello to everybody, I am building my forms with zod as a validation solution. Currently I am struggling with finding out, if a field inside an object is required or not. I use this, to display the red asterisk next to a form field so that my schema definition from zod is used for the display and always in sync with the user interface. I have been using the following snippet which has worked out so far:
const isRequired = (name, schema) => !schema._def.shape()[name]?.isOptional(),
This introspects the schema deeper in the tree of my components and checks if inside the _def.shape()
object there is a field with name
that is not optional.
Right now I have a more complex form approach where I am using superRefine
to manually add issues for a field to be required so this approach doesn’t work:
const schema = z.object({
attendeeType: z.nativeEnum(AttendeeType),
company: z.string().optional(),
}).superRefine(({ attendeeType, company }, { addIssue }) => {
if (attendeeType === AttendeeType.BUSINESS && !company) {
addIssue({
code: TOO_SMALL,
inclusive: true,
minimum: 1,
path: ['company'],
type: 'string'
})
}
})
Has someone an idea how I get this information for all cases?
Issue Analytics
- State:
- Created 9 months ago
- Reactions:2
- Comments:5 (3 by maintainers)
Top GitHub Comments
Hey @maxArturo thank you for your answer. I ended up building a function that dynamically loops through all effects until it finds a
ZodObjectDef
with.shape()
to work with:Still this very inner type has the
.optional()
property, so calling.isOptional()
still returns true, since it does not pick up the effects from zod in my case. Am I missing something? Does.sourceType()
work different?@micah-redwood I am working with the same implementation by using
react-hook-form
. For now I use a manual flag to set the field to required, if I have a schema that uses.refine()
, or.superRefine()
. For cases without it, I do not need to set a prop to my component since my posted function does serve my purpose.@dominikspiertz
sourceType()
“pulls out” the inner validator from the effects, so its a quality of life overinnerType()
:Also,
optional()
is defined for all schemas so everything will have.optional()
unfortunately. Feel free to do this instead (I tried it out locally and it should work for arbitrary levels of nesting of.refine()
:Just keep in mind that if your innermost
ZodObject
has nested attributes, you’ll have to make sure to traverse those yourself at the end. And if this helps solve your issue, please feel free to close it. Thanks!