Unable to create an object with readonly property
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.
Hey, can I take a look at this matter? I can see what's going on and hopefully find a solution to this problem
@dmeehan1968 this sounds like an issue with Zod, but in the meantime a solution to this could be:
type ReadonlyProp<
T extends Record<string, unknown>,
Prop extends keyof T,
> = Readonly<Pick<T, Prop>> & Omit<T, Prop>
const schema = z
.object({
id: z.string().readonly(),
description: z.string(),
})
.transform((values) => values as ReadonlyProp<typeof values, 'id'>)
type Output = z.infer<typeof schema>
/*
{
readonly id: string;
description: string;
}
*/
This way any typecasting stays within the schema
The same issue
I ran into a similar problem. I've submitted a solution as PR #3533 which allows for the props to be marked readonly and also to extend the resulting schema using the extend method. This allows for the creation of schemas with only some properties being readonly while also being generally extendable.
Hi, @dmeehan1968. I'm Dosu, and I'm helping the Zod team manage their backlog. I'm marking this issue as stale.
Issue Summary:
- You reported an issue with creating a Zod schema with a readonly property for primitive types using
z.string().readonly(). - @kamilwezgowiec suggested a workaround using a custom type transformation.
- @llowrey submitted a pull request (#3533) to allow properties to be marked as readonly while enabling schema extension.
- @Isaac-alencar expressed interest in further investigation.
Next Steps:
- Please let me know if this issue is still relevant to the latest version of Zod. If so, you can keep the discussion open by commenting on the issue.
- Otherwise, the issue will be automatically closed in 14 days.
Thank you for your understanding and contribution!
What is the status of this issue. I am still facing this over a year later in a cloudflare worker, which as part of the response of a post endpoint has an id property that should not be present on the request.