I’m working with a validation schema using Zod, where I have an items field that represents an array of objects. In this scenario, I’m specifically using it for invoice items. Each item is an object with various properties.
I’m facing a challenge in defining a validation schema that enforces the following condition: If the id
property within an item is set, then all other fields within that item should be optional (indicating that the item is being updated). Conversely, if the id
property is not set, then all other fields should be required (indicating that a new item is being created).
How can I achieve this conditional validation in Zod?
items: z.array(z.object({
id: z.number({required_error: "'id' is required", invalid_type_error: "'id' must be a number"}).positive("'id' must be a positive number").optional(),
articleId: z.number({required_error: "'articleId' is required", invalid_type_error: "'articleId' must be a number"}).positive("'articleId' must be a positive number"),
sku: z.number({required_error: "'sku' is required", invalid_type_error: "'sku' must be a number"}).positive("'sku' must be a positiv number"),
description: z.string({ required_error: "'description' is required" }).nonempty("'description' cannot be empty").max(1000, { message: "'description' is too long" }),
quantity: z.number({required_error: "'quantity' is required", invalid_type_error: "'quantity' must be a number"}).positive("'quantity' must be a positive number"),
price: z.number({required_error: "'price' is required", invalid_type_error: "'price' must be a number"}).positive("'price' must be a positive number"),
term: z.enum(["month", "year", "flat", "piece"], { required_error: "'term' is required" }),
})),
2
Answers
Have you tried
z.or()
?You can try using superRefine method to add conditional validation to your previous schema like this:
This code was adapted from this repository on GitHub, which contained an implementation similar to yours: https://github.com/colinhacks/zod/discussions/938#discussioncomment-6952970
I hope this solves your problem.