I'm trying to create a dictionary like zod schema for an object that has many keys, defined elsewhere, and they all have the same value type. And all keys are required.
const KeysSchema = z.enum(['a', 'b', 'c', /*...*/]) // long key list
const ObjSchema = z.record(KeysSchema, z.number())
But the yielded type is:
{
a?: number | undefined;
b?: number | undefined;
c?: number | undefined;
}
But what I want is:
{
a: number;
b: number;
c: number;
}
I want: Record<'a', 'b', 'c', number>
but it's giving me: Partial<Record<"a" | "b" | "c", number>>
And I can't call z.record(...).required()
because that's not a thing for zod records.
How can I make a record type with required keys?
Managed to solve it with a .refine()
.refine((obj): obj is Required<typeof obj> =>
KeysSchema.options.every((key) => obj[key] != null),
)
It checks every key in the KeysSchema
and asserts that all keys are present, and it's not a partial at all.