为泛型PaginatedResponse接口创建Zod Schema时,items字段如何定义?
如何将泛型分页接口转换为Zod Schema?
我定义了一个用于分页响应的泛型TypeScript接口:
export interface PaginatedResponse<T> { pageIndex: number; pageSize: number; totalCount: number; totalPages: number; items: Array<T>; }
现在想把它转换成Zod Schema做运行时类型校验,目前的实现框架如下,但不知道items字段该用什么类型的数组:
const PaginatedResponseSchema = z.object({ pageIndex: z.number(), pageSize: z.number(), totalCount: z.number(), totalPages: z.number(), items: z.array(???), // 这里应该填什么? }); export type PaginatedResponse<T> = z.infer<typeof PaginatedResponseSchema>;
解决方案
因为你的分页接口是泛型的,需要适配不同类型的items,所以不能直接写死z.array()的参数,得把Zod Schema做成泛型函数,动态传入具体的item校验规则。
完整实现代码
import { z } from "zod"; // 定义泛型函数,接收具体的item Schema,返回对应的分页响应Schema const createPaginatedResponseSchema = <T extends z.ZodTypeAny>(itemSchema: T) => z.object({ // 可以给分页字段加上更严格的校验(比如非负整数、正整数) pageIndex: z.number().int().nonnegative(), pageSize: z.number().int().positive(), totalCount: z.number().int().nonnegative(), totalPages: z.number().int().nonnegative(), items: z.array(itemSchema), // 这里传入动态的item Schema }); // 示例:针对User类型的分页响应 const UserSchema = z.object({ id: z.string(), name: z.string(), email: z.string().email(), }); // 创建User分页响应的Schema const PaginatedUserResponseSchema = createPaginatedResponseSchema(UserSchema); // 推导泛型类型 export type PaginatedResponse<T> = z.infer<ReturnType<typeof createPaginatedResponseSchema<T>>>; // 或者推导具体类型 export type PaginatedUserResponse = z.infer<typeof PaginatedUserResponseSchema>;
说明
- 泛型函数的作用:通过
createPaginatedResponseSchema函数,你可以给任意类型的item创建对应的分页响应Schema,复用性更强。 - 增强校验规则:比起原TypeScript接口,Zod可以给
pageIndex、pageSize等字段加上int()(整数)、nonnegative()(非负)、positive()(正整数)这类运行时校验,避免非法值。 - 类型推导:通过
z.infer可以自动从Zod Schema推导出对应的TypeScript类型,不需要手动重复定义接口。
内容的提问来源于stack exchange,提问作者ligowsky
相关产品推荐
相关产品推荐

