Exploring Zod and the Benefits of Schema-Based Validation in TypeScript Projects

RMAG news

Introduction

This post explores Zod, a library that provides “TypeScript-first schema validation with static type inference”. We’ll explore how it works and why it’s so useful.

Manual Validation

If you’ve found yourself manually writing validation checks it can get tedious pretty quickly. For example, you might need to write checks to make sure that required fields are provided and data is in the correct format and/or fits certain parameters like a number being within a certain range.

if (name === ) {
errors.push(Name is required)
}

if (name.length < 3) {
errors.push(Name must be at least 3 characters)
}

if (name.length > 30) {
errors.push(Name must be 30 or fewer characters long)
}

Schema Validation

This is where Zod comes in really handy. Here’s an example of how we can define a userSchema where name, age, email are all required with their expected types and a min/max length for the name. To make it optional you will need to add .optional().

import { z } from zod;

// Define the schema with validation rules
const userSchema = z.object({
name: z.string().min(3).max(30),
age: z.number(),
email: z.string().email()
});

// Infer TypeScript type from the schema
type User = z.infer<typeof userSchema>;

// Parse data using the schema and handle the result
const result = userSchema.safeParse({ name, age, email })

if (result.success) {
// Everything looks good and valid
} else {
// Invalid… handle using result.error
}

Using z.infer you can infer the TypeScript type from the Zod schema which is also really handy to avoid duplication and have it automatically update when the userSchema is updated.

Zod provides detailed validation messages which can also be customised like so:

const name = z.string({
required_error: Name is required,
invalid_type_error: Name must be a string,
});

Conclusion

Zod is a great tool to write cleaner and simpler code for validation. Share your experiences with these tools in the comments.

Leave a Reply

Your email address will not be published. Required fields are marked *