Search code examples
javascripttypescriptvalidationschemazod

How to make all properties optional in a Zod schema based on a specific product availability flag?


I have a Zod schema that validates product properties for an e-commerce application. In my schema, I currently have a property called isLimitedEdition which indicates whether a product is available in limited quantities. However, when isLimitedEdition is set to true, I want all other properties in the schema to become optional.

Here's the existing schema structure:

const productProperties = z.object({
  name: z.string().nonempty(),
  description: z.string().nonempty(),
  price: z.number().positive(),
  category: z.string().nonempty(),
  brand: z.string().nonempty(),
  isFeatured: z.boolean().default(false),
  isLimitedEdition: z.boolean().default(false),
});

In this schema, I want to achieve a behavior where all properties (name, description, price, category, brand, isFeatured) become optional if isLimitedEdition is set to true.

How can I modify this schema to achieve the desired behavior? I would appreciate any guidance or code examples to help me implement this logic correctly. Thank you in advance!

I tried the refine method but it didn't work


Solution

  • You can achieve this with discriminatedUnion:

    const productProperties = z.object({
      name: z.string().nonempty(),
      description: z.string().nonempty(),
      price: z.number().positive(),
      category: z.string().nonempty(),
      brand: z.string().nonempty(),
      isFeatured: z.boolean().default(false),
    })
    
    const product = z.discriminatedUnion('isLimitedEdition', [
      productProperties.extend({ isLimitedEdition: z.literal(false) }),
      productProperties.partial().extend({ isLimitedEdition: z.literal(true) }),
    ])