Zod and everything I love about it

Zod is a Typescript-first schema validation library that allows you to validate data structures. It provides a declarative and composible way to define schemas that cab be used to validate and generate Typescript types.

With Zod, you can define schemas for a wide variety of data types, including strings, numbers, booleans, arrays, objects and more.

Let’s see some examples!

Suppose, you have an user like this:

const user = {
  name: 'test-joy-03',
  firstName: 'Test',
  lastName: 'Joy',
  type: 'general',
  email: 'test-joy-03@gmail.com',
  createdAt: '2020-04-04',
  isVerified: true,
}

We want to validate the user data, we can do this with zod like this:

import z from 'zod'

const userSchema = z.object({
  name: z.string(),
  firstName: z.string(),
  lastName: z.string(),
  type: z.enum(['general', 'admin']), // we have two types of user here
  email: z.string().email(),
  createdAt: z.string().datetime(),
  isVerified: z.boolean(),
})

In Zod, all fields are required by default. If we want to make a field optional, we will have to add optional() function to the field.

If we want to add an optional field call phone number in the user schema,

const userSchema = z.object({
  // rest of the fields
  phoneNumber: z.string().regex(validPhoneNumber).optional(),
  // regex pattern to verify the phone number
})

As there are two types of users, different types of users can have different fields. We can use the Discriminated unions to update our user schema.

const baseUserSchema = z.object({
  name: z.string(),
  firstName: z.string(),
  lastName: z.string(),
  email: z.string().email(),
  createdAt: z.string().datetime(),
  isVerified: z.boolean(),
})

const userTypeSpecificSchema = z.discriminatedUnion('type', [
  z.object({
    type: z.literal('general'),
    subscriptionType: z.enum(['free', 'premium']),
    subscriptionEndDate: z.string().datetime().nullable(),
    // subscriptionEndDate can be null if the user uess a free account
  }),
  z.object({
    type: z.literal('admin'),
    // list of tasks this user can perform as an administrator
    permissions: z.array(z.string()),
  }),
])