Zod Guide
TypeScript-first schema validation with static type inference
Intro
Zod is a fantastic utility package by @colinhacks that allows for defining runtime schema validation and type-safety.
We use it extensively internally at Trigger.dev.
But there are a few places where we ask you to provide us with a Zod schema, for example when defining your own events:
So it will help to know a little about Zod and how to use it. We definitely recommend the well written Zod README but we’ve included a short primer below.
Wherever we require you to pass in a Zod schema, you can always start with z.any()
which accepts
any
type and then add more strict validations later.
Basic Usage
There are three main steps to using Zod:
- Define a schema
- Infer TypeScript types from the schema
- Validate data against the schema
When using Zod with Trigger.dev, you’ll only really need to do the first step, and by passing it to us (through the schema
property of the customEvent
function), we’ll do the second and third steps for you.
Defining Schemas
Primitives
Zod schemas are a way to define the shape of an object. They can be as simple as a single type, or as complex as a nested object.
Any schema can be marked as optional, which means the schema can be undefined
or null
:
Schemas can also be marked optional by providing a default value:
If you need to allow a value to be null
, you can use nullable()
:
You can also use Zod to coerce primites into other types. For example, you can coerce a string into a number:
The following primitives are supported:
Coercing dates are especially useful when you are receiving a string
from an API and want to convert it to a JavaScript Date
object:
Objects
Object schemas are the most common type of schema. They allow you to define the shape of an object, and the types of each property.
All properties are required by default, although you can make them all optional using partial()
:
You can also make individual properties optional:
By default an object schema will strip out any extra properties that are not defined in the schema. You can disable this behavior using passthrough()
:
Or you can use strict()
to make the schema throw an error if there are any extra properties:
Zod includes a few useful object schema utilities to help with reusing schemas, extends()
and merge()
:
You can also use pick()
and omit()
to create a new schema that only includes or excludes certain properties:
Arrays
You can specify the schema of an array using z.array()
:
You can also specify the type of array that has a fixed number of elements using z.tuple()
:
Unions
You can specify a union of schemas using z.union()
:
Discriminating unions are also supported, and especially useful when paired with type narrowing:
Records
You can specify a record of schemas using z.record()
, useful for when you have a map of values but don’t care about the keys:
JSON type
If you want to accept any valid JSON value, you can use the following schema:
Hat tip to ggoodman for this one.
Resources
Matt Pocock @mattpocock has a great free Zod Tutorial up on Total Typescript that covers the basics of Zod.
Easily generate Zod schemas from JSON, JSON Schemas, or TypeScript types.
Was this page helpful?