Search code examples
typescriptzod

How to merge multiple Zod (object) schema


I've 3 schema for a blog post.

  1. Image post
  2. Video post
  3. Text post

Schema look like this

// will be used for form validation

// text can be added but image required
const imagePostSchema = z.object({
  body: z.string().max(500).optional().or(z.literal('')),
  attachmentType: z.literal('img'),
  attachment: // z... image validation is here
});

// text can be added but video required
const videoPostSchema = z.object({
  body: z.string().max(500).optional().or(z.literal('')),
  attachmentType: z.literal('video'),
  attachment: // z... video validation is here
});

// text is required & other fields must be null
const textPostSchema = z.object({
  body: z.string().max(500),
  attachmentType: z.null(),
  attachment: z.null()
});

Now how to merge this schema's to make one schema so user can make any type of (this 3) post?


Solution

  • Merging into a schema that accepts "any type of these 3" is done by a union of the three types, using ….or(…) or z.union(…). However, since those types are to be distinguished based on their attachmentType, you really want a discriminated union which will make checking more efficient:

    const postSchema = z.discriminatedUnion("attachmentType", [
      imagePostSchema,
      videoPostSchema,
      textPostSchema,
    ]);