zod
zod copied to clipboard
Feature request: `.deepStrict`
Like .deepPartial
is to .partial
it would be beneficial to have a .deepStrict
function that ensures every level in an object, array, or tuple hierarchy is .strict
.
For example, this code does not generate a ZodError:
const person = z
.object({
name: z.string(),
meta: z.object({
born: z.string(),
}),
})
.strict();
person.parse({
name: "bob dylan",
meta: {
born: "a place",
extraKey: 61,
},
});
With .deepStrict
it would work like this:
const person = z
.object({
name: z.string(),
meta: z.object({
born: z.string(),
}),
})
.deepStrict();
person.parse({
name: "bob dylan",
meta: {
born: "a place",
extraKey: 61,
},
});
// => throws ZodError
This is very hard to do in the static domain. Currently .deepPartial
is very limited and error-prone for similar reasons. I'll leave this open but I recommend using z.strictObject
if you want a shorthand for declaring lots of strict objects without needing a method.
Thank you for considering this Colin, that's fair enough. Thank you for the reference to z.strictObject
, I didn't see that, much nicer than calling .strict()
on every object.
When using Joi there is kind of a "global" option you can enable so that the strict
feature will be applied recursively across all your objects by default. For sure it is a challenge to make such configuration reflect statically in the types but maybe it is a really good improvement to Zod to introduce such feature in runtime only at least.
Not sure about the implementation details but from the developer perspective it would be something like this:
schema.safeParse({
deepStrict: true,
})
Would be nice to have such deepStrict: true
option to cover cases, when extra keys are not welcomed.
Not only it would allow to define more clear schemas - without the need to add .strict()
or use .strictObject()
everywhere, but also support cases requested in #1449, when we need to use the same shared schemas in both ways - as strict and "normal" ones.
Having the behaviour of the schema change based on the parsing seems like a mistake to me. There would be no way to account for it in conversion / translation and it could act inconsistently in different parts of the code with no compiler errors to show for it.
As per received feedback - changed to .deepStrict()
method in newly opened PR
const person = z
.object({
name: z.string(),
meta: z.object({
born: z.string(),
}),
})
.deepStrict();
person.parse({
name: "bob dylan",
meta: {
born: "a place",
extraKey: 61,
},
});
// => throws ZodError
Another option would be something like:
z.strict().object({ ... })
You could think of this as a mode where strict is the default and loose is opt-in.
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.