- Published on
Creating Zod Schema for Generic Interface
- Authors
- Name
- Ripal & Zalak
Creating a Zod schema for a generic interface is a common requirement when dealing with runtime type checks. In this guide, we’ll explore how to define a Zod schema for a generic PaginatedResponse
interface.
The Problem
You have a TypeScript generic interface for a paginated response:
export interface PaginatedResponse<T> {
pageIndex: number
pageSize: number
totalCount: number
totalPages: number
items: Array<T>
}
Now, you want to create a Zod schema for runtime validation. However, the challenge lies in defining the items
array with a type that depends on T
.
Solution: Generic Zod Schema
Step 1: Create a Generic Function
You can use a generic function to generate a schema for PaginatedResponse
based on the schema for the items
field. Here’s how you can do it:
import { z } from 'zod'
function createPaginatedResponseSchema<ItemType extends z.ZodTypeAny>(itemSchema: ItemType) {
return z.object({
pageIndex: z.number(),
pageSize: z.number(),
totalCount: z.number(),
totalPages: z.number(),
items: z.array(itemSchema),
})
}
Step 2: Use the Function to Define a Schema
For example, if T
is a string, you can create the schema as follows:
const stringPaginatedResponseSchema = createPaginatedResponseSchema(z.string())
You can infer the TypeScript type from this schema:
export type StringPaginatedResponse = z.infer<typeof stringPaginatedResponseSchema>
Step 3: Support Other Types
You can use the same function to create schemas for other types. For example:
Schema for a User Object
const userSchema = z.object({
id: z.number(),
name: z.string(),
})
const userPaginatedResponseSchema = createPaginatedResponseSchema(userSchema)
export type UserPaginatedResponse = z.infer<typeof userPaginatedResponseSchema>
Schema for a Custom Type
const customTypeSchema = z.object({
key: z.string(),
value: z.any(),
})
const customPaginatedResponseSchema = createPaginatedResponseSchema(customTypeSchema)
export type CustomPaginatedResponse = z.infer<typeof customPaginatedResponseSchema>
Key Benefits
- Reusability: The generic function can handle any type of
items
field. - Type Safety: Leverage TypeScript’s type inference with Zod.
- Runtime Validation: Ensure data integrity with Zod’s runtime checks.
FAQ
Q1: Can I infer a type directly from the schema?
Yes, use z.infer<typeof schema>
to derive the TypeScript type from your Zod schema.
Q2: How do I customize error messages?
You can pass a message
property to Zod methods like z.number()
or z.array()
:
z.number({ message: 'Must be a number' })
Q3: Is this approach compatible with React?
Yes, Zod works well with React and other frameworks. Use it to validate API responses or form inputs.