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()),
}),
])