zod
zod copied to clipboard
suggestion: z.record() should support .max() and .min() to specify a number of properties
Apologies if this is a duplicate - I wasn't able to find any existing discussion on this topic.
I have a use case where I'm trying to replicate the behaviour of the minProperties / maxProperties (see https://json-schema.org/draft/2020-12/json-schema-validation#name-validation-keywords-for-obj).
I can currently achieve this like so:
const TestSchema = z.record(z.string()).refine(
value => {
const propertyCount = Object.keys(value).length;
return propertyCount >= 1 && propertyCount <= 3;
},
{
message: 'Invalid input: must have between 1 and 3 properties',
},
);
Which results in:
TestSchema.safeParse({}).success; // false
TestSchema.safeParse({ a: 'foo' }).success; // true
TestSchema.safeParse({ a: 'foo', b: 'bar', c: 'baz' }).success; // true
TestSchema.safeParse({ a: 'foo', b: 'bar', c: 'baz', d: 'buz' }).success; // false
I'm proposing that there's an API like so:
const TestSchema = z.record(z.string()).min(1).max(3);
that behaves the same way, primarily so that JSON schema generation tools can read min
and max
here to fill in the maxProperties
and minProperties
fields in their generated schemas.
It may be more useful for this to be extended more generally into a minProperties()
and maxProperties()
that is usable for anything that resembles a z.object
, so that it can deal with more complex intersections and constructions of objects than just records. It also may be useful to include a .length()
equivalent (though at this moment I don't have use for it).