I'm wondering how to go about creating a 'partial' record in TypeScript using Zod, so it can be used for runtime type parsing. I'll try to explain with an example.
const ZodRecord = z.record(z.string(), z.string())
type ZodRecord = z.infer<typeof ZodRecord>
const zodRecord: ZodRecord = {
foo: 'foo',
}
console.log(zodRecord.foo.toUpperCase())
console.log(zodRecord.bar.toUpperCase())
At transpile time, and in the editor, this works just fine. However, at runtime, of course a TypeError
is thrown: Cannot read properties of undefined (reading 'toUpperCase')
.
I know that protection against this can be achieved using TypeScript's builtin type system, like this;
type PartialRecord = Partial<Record<string, string>>
const partialRecord: PartialRecord = {
foo: 'foo',
}
Using this record, a statement such as console.log(partialRecord.foo.toUpperCase())
does not transpile, with a warning that partialRecord.foo is possibly 'undefined'
. How do I achieve the same thing in Zod? I know that there is a .partial()
method for Zod objects, but in this particular case I need to use a record because the keys of the record are generated at runtime.
All the best!