[Zod] Create Custom Zod Schemas and Validate project-specific data
The example case covers room numbers validation: it must start with an uppercase letter followed by three digits. z.custom
allows the creation of a brand new custom schema with a callback function that returns a boolean indicating validity.
We highlight a challenge with type inference in Zod's custom schemas: callback parameter types don't get aligned automatically - type-safety must be explicitly defined using type parameters.
We run tests against various room numbers and demonstrate how to effectively validate inputs and manage error messages.
import { z } from 'zod'
// If you just want to validate a string with a regex, z.string().regex(...) is simpler:
const RoomNumberSchema = z
.string()
.regex(/^[A-Z]\d{3}$/, {
message: 'Invalid room number: must be 1 uppercase letter + 3 digits',
})
// But if you need more control — for example, returning custom error data or applying
// multi-step validations — you can use z.custom() with a callback:
const roomNumberPattern = /^[A-Z]\d{3}$/
const RoomNumberSchemaCustom = z.custom<string>((val) => {
return roomNumberPattern.test(val)
}, {
message: 'Invalid room number',
})
// Both approaches will throw an error on bad inputs like "A1", "101A", "B2050", etc.