Introduction
TypeScript brings static typing to JavaScript, allowing developers to catch potential errors during development. However, as your codebase grows, ensuring type safety becomes increasingly challenging. Enter Zod, a TypeScript-first schema declaration and validation library that aims to make working with data structures and validation a breeze.
In this blog post, we will explore Zod in TypeScript, understand its core concepts, and walk through practical examples to demonstrate how it can be a valuable tool in your development arsenal.
Getting Started with Zod
Firstly, letās install Zod using npm or yarn:
npm install zod
# or
yarn add zod
Requirements
- TypeScript 4.1+!
- You must enableĀ
strict
Ā the mode in yourĀtsconfig.json
. This is a best practice for all TypeScript projects.
// tsconfig.json
{
// ā¦
"compilerOptions": {
// ā¦
"strict": true }
}
Now, letās dive into the basics of Zod.
Defining Schemas with Zod
Zod allows us to define data schemas, specifying the shape and types of our data. Hereās a simple example:
// Import the Zod library for data validation
import { z } from ''zod'';
// Define a schema for user objects, ensuring data integrity
const userSchema = z.object({
// Define properties with their expected types and validations:
id: z.string(), // Must be a string
username: z.string(), // Must be a string
email: z.string().email(), // Must be a string in a valid email format
age: z.number().int().positive(), // Must be a positive integer
});
// Create an example user object to validate
const user = {
id: ''123'',
username: ''john_doe'',
email: ''john.doe@example.com'',
age: 10,
};
// Validate the user object against the schema
const validatedUser = userSchema.parse(user);
// If validation succeeds, validatedUser will contain the parsed user object.
// If validation fails, an error will be thrown.
console.log(validatedUser); // Output the validated user object or any errors
In this example, we define a schema for a user object, specifying thatĀ id
Ā andĀ username
Ā should be strings,Ā email
Ā should be a valid email address, andĀ age
Ā should be a positive integer. TheĀ parse
Ā method validates the user object against the schema.
Custom Validation and Transformation
Zod allows us to add custom validation and transformation functions. Letās enhance our user schema with a custom validation for the username and a transformation for the age:
// Define a schema for product objects, ensuring data integrity
const productSchema = z.object({
// Define properties with their expected types and validations:
id: z.string(), // Must be a string
name: z.string(), // Must be a string
price: z.number().int().positive(), // Must be a positive integer
});
// Custom validation function for name
const isValidProductname = (name: string) => /^[a-zA-Z0-9_]+$/.test(name);
// Custom transformation function for price
const doublePrice = (price: number) => price * 2;
// Extend the product schema with custom validation and transformation
const extendedProductSchema = productSchema.extend({
name: z.string().refine(isValidProductname, {
message: ''Invalid Product format'',
}),
price: z.number().transform(doublePrice),
});
// Example user with a custom name and price transformation
const productWithCustomData = {
id : "123",
name: ''chair'',
price: 15,
};
// Validate and transform the product data against the extended schema
const validatedProductWithCustomData = extendedProductSchema.parse(productWithCustomData);
console.log(validatedProductWithCustomData);
// { id: ''123'', name: ''chair'', price: 30 }
Here, we use theĀ refine
Ā method for custom validation of theĀ name
Ā field and theĀ transform
Ā method to double the value of theĀ price
Ā field.
Array Validation
Letās consider a scenario where we have an array of user objects, and we want to ensure that each user in the array conforms to a specific schema:
// Define a schema for individual user objects
const userSchema = z.object({
id: z.string(),
username: z.string(),
email: z.string().email(),
age: z.number().int().positive(),
});
// Define a schema for arrays of user objects
const arrayOfUsersSchema = z.array(userSchema);
// Example array of users to validate
const users = [
{
id: ''123'',
username: ''john_doe'',
email: ''john.doe@example.com'',
age: 25,
},
{
id: ''456'',
username: ''the_rock'',
email: ''the.rock@example.com'',
age: 25,
},
];
Here,Ā arrayOfUsersSchema
Ā is a schema that expects an array of objects, where each object adheres to theĀ userSchema
. TheĀ parse
Ā method ensures that each element in the array satisfies the specified schema.
Advanced Schema Composition (or, and)
Zod supports advanced schema composition with union and intersection types. Letās create schemas for both individuals and organizations:
const individualSchema = z.object({
firstName: z.string(),
lastName: z.string(),
});
const organizationSchema = z.object({
organizationName: z.string(),
registrationNumber: z.string(),
});
// Union type: person or organization
const entitySchema = individualSchema.or(organizationSchema);
// Example individual data
const individualData = {
firstName: ''John'',
lastName: ''Doe'',
};
const validatedIndividual = entitySchema.parse(individualData);
console.log(validatedIndividual);
// InterSection type: person and organization
const individualAndOrganizationSchema = individualSchema.and(organizationSchema);
const individualDataIntersection = {
firstName: ''John'',
lastName: ''Doe'',
organizationName : ''08744'',
registrationNumber : ''94774'',
};
const validatedIndividualInterSection = individualAndOrganizationSchema.parse(individualDataIntersection);
console.log(validatedIndividualInterSection);
In this example, we define separate schemas for individuals and organizations, then create a union type (or
) and an intersection type (and
) to compose more complex schemas.
Conclusion
Zod is a powerful tool for defining, validating, and transforming data structures in TypeScript. With its concise syntax and extensive features, it can enhance the robustness and maintainability of your codebase. As you explore Zod further, youāll find it to be a valuable asset in handling data with confidence.
Remember to check theĀ official documentationĀ for more advanced features and options provided by Zod. Happy coding!