想去哪里?

首页 页面 关于 页面 项目 页面 简历 页面 技术 页面 随笔 页面 联系 页面 隐私政策 页面 Terminal Spike 隐私政策 页面 用 Astro 构建文档与职业个人网站 技术 通过 tmux、Mosh、Termius 与 Tailscale 随处使用 Codex 技术 用 Langfuse 观察 Codex 的 MCP 工具调用 技术 产品应用中的本地化 技术 把 MCP 作为安全的 AI 集成边界 技术 用 Zod、OpenAPI 与 Swagger 维护 API 契约 技术 用 pg-boss 运行持久后台任务 技术 通过真实知识工作流理解 pgvector 与 RAG 技术 Pi Edge:让 Pi 待在 Obsidian 笔记旁 技术 为真实排序任务设计拖放交互 技术 Prisma 与 PostgreSQL:产品状态的事实来源 技术 把 Ralph Loop 当作计划队列 技术 用 React Router 组织全栈产品工作流 技术 把 shadcn 风格组件变成自己的产品系统 技术 用表格与编辑器承载密集业务操作 技术 Terminal Spike:原生 Android 终端 技术 在 Linux 上用 fcitx 输入带声调的拼音 技术 在 Linux 上配置 DEFT Pro 轨迹球 技术 在 KOReader 上使用 Pocket 稍后读 技术 为 Vercel AI SDK 设置明确的工具边界 技术 垂直切片架构与 dependency-cruiser 技术 用 Vitest 与 Playwright 测试产品工作流 技术 我的随处工作流:Herdr、code-server、Obsidian 与 Pi Edge 技术 Zod 不只是校验 技术 《卡拉马佐夫兄弟》是我看过最好的小说 随笔 基督徒口述1960劳改历史 随笔 圣经中的“道”与言语 随笔 我们爱,因为神先爱我们,而不是空洞的“自爱” 随笔 妈妈,让我来承担爸爸的过错吧 随笔 我与神的故事 随笔 世界远离上帝,接近中国 随笔 “爱的五种语言”和内外向,只存在于语言中 随笔 人格类型不存在,你在世界而非概念中生活 随笔 危险的词语:为什么心理学是不可能的 随笔 2000 年,一个深圳打工者的故事 随笔 阿联酋Ras al Khaimah见闻录 随笔 沙甸:1975 年的一场冲突 随笔 关于中国的纪录片 随笔
← 技术/工程实践

Zod 不只是校验

用运行时 schema 描述边界、规范输入,并保持 API 与 UI 契约一致。

Zod 通常被介绍为校验库,但更有用的理解是边界定义。

TypeScript 类型主要帮助程序内部的数据,Zod 则帮助守住数据从表单、API、环境变量、导入文件和 AI 工具调用进入的边缘。

const ImportRowSchema = z.object({
  name: z.string().trim().min(1),
  quantity: z.coerce.number().int().positive(),
});

这个 schema 不只校验,也说明边界预期。trim 和强制转换都是小型规范化决策,会改变产品接受什么,应有意识地选择。

schema 应靠近它保护的边界。表单 schema 描述表单输入,API schema 描述公开请求,数据库模型不应自动成为外部契约。

数据库可能有用户不该发送的字段,API 可能接受比内部模型简单的结构,表单解析前也可能以字符串表示数字。到处复用同一 schema 看似高效,却可能隐藏不同职责。

Zod 也有助于统一错误处理,让多个路由以可预期结构返回字段错误:

{
  "fields": {
    "quantity": "Quantity must be a positive number."
  }
}

格式本身不如一致性重要。用户和 API 客户端不应为每个接口学习一套错误形式。

取舍在于 schema 可能过于聪明。大型转换、隐藏默认值和复杂 refinement 会让接受什么变得难看清。开始包含真正产品决策时,我通常将决策移到服务,让 schema 专注边界。

我会用它处理表单输入、API 请求体、查询参数、导入行、环境变量和 AI 工具参数。

Zod 不应成为整个领域模型。它擅长边缘,应用其他部分仍需清楚的服务、权限与持久化规则。

如果 schema 让边界更容易审查,它就在帮忙;如果它把工作流藏进一堆转换,就做得过多了。