zod icon indicating copy to clipboard operation
zod copied to clipboard

Unable to create an object with readonly property

Open dmeehan1968 opened this issue 1 year ago • 4 comments

Possibly related to #728, but without the need for recursive application to the object properties.

z.object({
  id: z.string().readonly(),
  description: z.string(),
})

As of Zod 3.22.2, syntactically this is acceptable, but based on the description of readonly() it probably should not apply to primitive types). The resulting type drops the readonly and gives { id: string, description: string }.

I also tried an intersection of objects:

z.intersection(
  z.object({ id: z.string() }).readonly(),
  z.object({ description: z.string() })
)

But this oddly gives { id: any, description: string }, thus losing both the type and the readonly protection.

In my application, I have entities where the ID should not be changed (storage requires the old entity to be deleted and one with a new identity created). Zod is preventing me from creating a schema that enforces this.

The only way I can figure out how to set the id to be readonly is to cast the return type from parse, e.g:

schema.parse(input) as (z.infer<typeof schema> & { readonly deviceId: string })

or to create a type from the schema with a similar union:

type X = z.infer<typeof schema> & { readonly deviceId: string }

which seems like a total fudge.

dmeehan1968 avatar Sep 13 '23 07:09 dmeehan1968