跳到主要内容

数据验证:TypeScript To Zod Schema — Numio

使用 ts-to-zod 根据 TypeScript interface 和类型生成 Zod schema。每个类型 Foo 会变为导出的 fooSchema,@format email 或 @minimum 等 JSDoc 标签会变为 Zod 校验器。

你的 API 类型已用 TypeScript interface 定义,想在不手写 schema 的情况下对传入请求做运行时校验。

TypeScript

Zod Schema

适用场景

  • 你的 API 类型已用 TypeScript interface 定义,想在不手写 schema 的情况下对传入请求做运行时校验。
  • 你用 Zod 校验表单输入,希望 schema 与共享的 TypeScript 类型保持一致。

使用方法

  1. 粘贴 TypeScript interface 或类型别名;添加 @minimum 13 或 @format email 等 JSDoc 标签即可生成校验器。
  2. 在设置中开启 Keep TSDoc Comments 可将注释复制到输出中,开启 Skip the creation of zod validators from JSDoc annotations 则忽略这些标签。
  3. 源码会通过 /api/typescript-to-zod 在服务器上转换;复制从 "zod" 导入 z 的代码即可。

TypeScript

export interface Signup {
  /**
   * @format email
   */
  email: string;
  /**
   * @minimum 13
   * @maximum 120
   */
  age: number;
  plan: "free" | "pro";
  referrer?: string | null;
  createdAt: Date;
}

Zod schema

import { z } from "zod"

export const signupSchema = z.object({
  email: z.string().email(),
  age: z.number().min(13).max(120),
  plan: z.union([z.literal("free"), z.literal("pro")]),
  referrer: z.string().optional().nullable(),
  createdAt: z.date(),
})

功能与限制

页面会把输入发送到服务器路由(/api/typescript-to-zod)进行转换,并不只在浏览器中处理。Next.js API 路由默认接受最大 1 MB 的请求体。

只转换类型。导出的函数和常量不会生成 schema。

如果某个类型引用了输入中没有的类型,转换器会报告缺少依赖的错误,而不会生成 schema。

schema 按依赖关系排序,因此像 Author 这样被引用的类型会先于使用它的类型输出。

FAQ

可选字段和 null 字段如何转换?

referrer?: string | null 会变为 z.string().optional().nullable();类型为 Author | null 的属性会变为 authorSchema.nullable()。

Date 如何处理?

Date 属性会变为 z.date(),它接受 Date 对象而不是 ISO 字符串。对于 JSON 输入,请使用 z.coerce.date()。

为什么会出现 "Some schemas can't be generated due to direct or indirect missing dependencies"?

某个类型引用了粘贴的代码中没有的类型。请把被引用的类型也一起粘贴。

规范与参考资料