Working with Zod

Throughout this tutorial, we'll be learning about the required steps of implementing schema validation in our web development projects with TypeScript and Zod. Zod is TypeScript library that helps you define schemas and run validations against objects that need to adhere to the schemas. We'll see why Zod is the chosen language for schema validation then we'll look at hands-on examples to understand how this works.

TypeScript has recently become the go-to language to build high-quality JavaScript apps. Its static type checking system helps developers by showing possible issues but this checking is only done during compilation. As a result, its limits become apparent as there is not validation during runtime when code is in execution.

Schema validation validates the structure of received data and guarantees that it matches a desired structure. Zod is an open source TypeScript library for defining and validating schemas. It works by defining Zod schemas to validate data for forms and APIs, etc.

Developers are always finding issues regarding data validation and type safety where they need to ensure that the data they manipulate (For example in forms or APIs) respect some predefined structures and constraints. Fortunately Zod is a powerful tool at our disposal. In this comprehensive tutorial, we'll be looking at Zod capabilities and how might be the best solution for implementing data validation in your TypeScript code.

Introducing Zod

Zod is a TypeScript-centric schema validation library with static type inference. It is created to provide runtime validation while also augmenting the type system of TypeScript. As a result, developers benefit from both compile-time type safety and runtime data validation.

Before tackling how to work with Zod, let's first grasp why schema validation is crucial in our JavaScript apps. Let's presume that we are building a web application that relies on the input from users. Without validation of the input, our app may receive data in unwanted formats from its users which results in runtime errors and security flaws. Proper schema validation helps the application process data that conform to predefined requirements and avoid these risks.

The ability to define data schemas with TypeScript types and then validate them in runtime save developers endless hours of troubleshooting. Zod has since merged easily into a lot of projects, becoming an important tool.

Working with Zod

Let's now see how to work with Zod with a hands-one project. Open a terminal and create a working directory, let's call it zod-hands-on and navigate to using these commands:

mkdir zod-hands-on && cd zod-hands-on 

Next, run the following command to install Zod:

npm install zod

This needs to have Node.js installed on your development machine.

Now, you can begin using Zod to define and validate schemas. Create an index.ts file:

touch index.ts

Next, copy and paste the following code:

import { z } from 'zod';

const loginUserSchema = z.object({
    email: z.string().email('Invalid email or password'),
    password: z.string()
  });

type LoginUser = z.infer<typeof loginUserSchema>;

This code shows how to use Zod for both schema validation and type inference in TypeScript.

We first import the z object from the zod library, making it possible for us to use its methods for schema validation.

Next, we define a schema called loginUserSchema using the z.object() method. Inside this schema, we specify the desired structure of data for a login user, where the email field must be a valid email address and the password field must be a string.

Finally we define a TypeScript type LoginUser by using the z.infer() method to infer the type from the loginUserSchema. In other words, LoginUser will represent the type of data that matches the schema defined in loginUserSchema, ensuring type safety throughout the code.

One notable feature of Zod is its smooth integration with TypeScript. This applies to more than simply runtime validation; it also provides you with enhanced type safety and autocomplete in your code editor.

Next, add the following code:

try {
  const validLogin = loginUserSchema.parse({
    email: "john.email.com",
    password: "123456789",
  });

  console.log(`email: ${validLogin.email} - password: ${validLogin.password}`);
} catch (e: any) {
  console.log(e.message);
}

Then run the TypeScript file using ts-node as follows:

 npx ts-node index.ts

Handling Errors with Zod

Since we have provided a wrong format for the email, parse() will throw this error:

[
  {
    "validation": "email",
    "code": "invalid_string",
    "message": "Invalid email or password",
    "path": [
      "email"
    ]
  }
]

Zod streamlines the process of handling validation errors. When data does not meet the schema specifications, Zod generates an error message that provides detailed information about the error in question.

If we correct the email, we'll get the our output:

email: [email protected] - password: 123456789

By calling the parse() method of the Zod schema, we make sure that the object we're working is valid.


  • Date: