Custom Validation with Zod and "Refine"

Zod offers a lot of great ways to validate your data.

But occasionally, you might need something a little more custom.

One of Zod's powerful features is the ability to perform custom validations using the refine method. This method allows you to add custom validation logic to a schema.

Here's how:

Custom Validation

We will start by defining a basic schema for the data you want to validate. For example, we will validate a booking form where a user has a departureDate and a returnDate. Here's the starter schema:

import { z } from "zod";

const bookingSchema = z.object({
  departureDate: z.date(),
  returnDate: z.date(),
})

Add Custom Validation with refine

Right now, our user can add any two dates. But we want to ensure that the returnDate is after the departureDate. Let's show you how you can easily add the custom validation by chaining the refine function to your schema:

import { z } from 'zod';

const bookingSchema = z.object({
  departureDate: z.date(),
  returnDate: z.date(),
}).refine((data) => data.returnDate > data.departureDate, {
  message: "Return date must be after departure date",
  path: ["returnDate"], // Optional: Specify the path for a more precise error location
});

// Now we can use our schema
try {
  bookingSchema.parse({
    departureDate: new Date('2024-03-01'),
    returnDate: new Date('2024-03-10'),
  });
  console.log("Booking dates are valid!");
} catch (error) {
  console.error(error.errors);
}

In this example, refine takes two arguments:

  • A validation function that returns true if the data passes the validation and false otherwise.
  • An options object where you can specify a custom error message and the path to the data being validated.
  • We also added an optional path to our returnDate so that our errors can be more specific.

This code validates an object against your schema and the refine function. If it fails, Zod will throw an error. You can catch this error and handle it as needed.

TypeScript
Avatar for Niall Maher

Written by Niall Maher

Founder of Codú - The web developer community! I've worked in nearly every corner of technology businesses: Lead Developer, Software Architect, Product Manager, CTO, and now happily a Founder.

Loading

Fetching comments

Hey! 👋

Got something to say?

or to leave a comment.