news 2026/9/3 12:01:50

Zod Codecs完全教程:用两行代码实现数据的双向编码解码(encode/decode)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Zod Codecs完全教程:用两行代码实现数据的双向编码解码(encode/decode)

Zod Codecs完全教程:用两行代码实现数据的双向编码解码(encode/decode)

【免费下载链接】zodTypeScript-first schema validation with static type inference项目地址: https://gitcode.com/GitHub_Trending/zo/zod

Zod是 TypeScript 生态中最流行的 schema 校验库,而Zod Codecs(自zod@4.1引入)是它最实用的新特性之一:用一行z.codec()就能定义数据的双向转换,decode把外部数据"解码"成你喜欢的类型,encode再"编码"回去,轻松搞定网络请求里 JSON 字符串与 JavaScript 对象之间的来回转换。

为什么需要 Zod Codecs?

做前后端开发时你一定遇到过这种尴尬:

  • 服务器发来的是 ISO 时间字符串"2024-01-15T10:30:00.000Z",代码里却想直接用Date对象
  • 表单提交来的数字是字符串"42.5",业务逻辑需要的是number
  • 发请求前又得把它们老老实实转回字符串

传统做法是两头各写一堆new Date(...).toISOString()转换代码,枯燥且容易漏。Zod Codecs 的解决方案是:把"校验"和"双向转换"合并进同一个 schema,客户端和服务器共享一份定义,decode/encode各管一个方向。

两行核心代码:z.codec() 基础用法

创建一个 Codec 只需三步:输入 schema、输出 schema、转换函数。以"ISO 字符串 ↔ Date 对象"为例:

const stringToDate = z.codec( z.iso.datetime(), // 输入 schema:ISO 日期字符串 z.date(), // 输出 schema:Date 对象 { decode: (isoString) => new Date(isoString), // 解码:字符串 → Date encode: (date) => date.toISOString(), // 编码:Date → 字符串 } );

使用极其清爽:

stringToDate.decode("2024-01-15T10:30:00.000Z"); // => Date 对象 stringToDate.encode(new Date("2024-01-15T10:30:00.000Z")); // => 字符串

💡 实现细节:z.codec()本质上是 packages/zod/src/v4/classic/schemas.ts 中的codec函数,内部把decode/encode分别挂成管道(pipe)的正向与反向转换函数。

parse 与 decode 的区别:类型签名不同

.parse().decode()运行时行为完全相同,但类型检查强度不同:

  • parse()接受unknown输入 —— 传错类型编译器不报错,运行时才失败
  • decode()/encode()输入强类型—— 传个数字进去,TypeScript 直接标红
stringToDate.parse(12345); // ✅ 编译通过(运行时才炸) stringToDate.decode(12345); // ❌ 编译报错:number 不能赋给 string

正因为 encode/decode 隐含"转换"语义,输入通常已是强类型,Zod 选择把错误提前暴露到编译期。

进阶技巧:让 Codec 融入复杂结构

1. 可组合性:嵌套到对象和数组里

Codec 就是普通 schema,想放哪放哪:

const payloadSchema = z.object({ startDate: stringToDate }); payloadSchema.decode({ startDate: "2024-01-15T10:30:00.000Z" }); // => { startDate: Date }

一个对象 schema 就能让整包数据自动完成双向转换,这是网络边界场景(API 请求/响应)最大的价值点。

2. z.invertCodec():一键反转方向

有了stringToDate,想要反方向的dateToString?不用重写:

const dateToString = z.invertCodec(stringToDate);

⚠️ 注意:它只反转你传入的那一层 codec,不会递归反转嵌套在其他 schema 里的 codec,嵌套层需要在使用处分别反转。

3. 异步与安全变体

.transform()一样支持异步转换函数,也有一整套"安全"API:

stringToDate.decodeAsync("2024-01-15T10:30:00.000Z"); // => Promise<Date> stringToDate.safeDecode("2024-01-15T10:30:00.000Z"); // => { success: true, data: Date } | { success: false, error: ZodError }

4. 内置的 stringbool:现成的双向转换器

z.stringbool()早于 Codecs 存在,如今内部已用 codec 重新实现,可把"true"/"false"/"yes"/"no"与布尔值互相转换:

const sb = z.stringbool({ truthy: ["yes", "y"], falsy: ["no", "n"] }); sb.decode("yes"); // => true sb.encode(false); // => "no"(取数组第一个元素)

避坑指南:encode 方向的规则细节

这是新手最容易踩坑的部分,规则可以总结为:

特性decode(正向)encode(反向)
.refine()/.min()等校验✅ 执行✅ 执行(两遍校验)
.default()/.prefault()✅ 应用❌ 不应用
.catch()✅ 应用❌ 不应用
.transform()✅ 执行直接抛运行时错误

几个关键细节:

  1. default 只在正向生效z.string().default("hello")decode(undefined)返回"hello",但encode(undefined)会报错——因为加了默认值后输入类型才变成| undefined,而 encode 的入参是强类型的输出侧。
  2. transform 是单向的。schema 里任何.transform()都会让encode()抛出运行时错误(不是 ZodError),看到Encountered unidirectional transform during encode就该去查是谁加了 transform。
  3. refine 是双向的。比如stringToDate.refine(date => date.getFullYear() >= 2000),encode 一个 1999 年的日期同样会触发校验失败。

常用 Codec 配方:直接抄作业

官方文档整理了一批经过测试的现成实现,建议你复制到自己的项目里按需修改(完整清单见 packages/docs/content/codecs.mdx):

  • stringToNumber/stringToInt:字符串转数字,如decode("42.5") => 42.5
  • epochSecondsToDate:Unix 时间戳(秒)与Date互转
  • json(schema):把 JSON 字符串解析成结构化数据并反序列化回去,出错时通过ctx.issues抛出带路径的invalid_format错误
  • base64ToBytes/hexToBytes:base64、十六进制字符串与Uint8Array互转
  • stringToURL:URL 字符串与URL对象互转
  • uriComponent:基于encodeURIComponent/decodeURIComponent的组件编码

一个最典型的 JSON codec:

const jsonCodec = (schema: any) => z.codec(z.string(), schema, { decode: (jsonString, ctx) => { try { return JSON.parse(jsonString); } catch (err: any) { ctx.issues.push({ code: "invalid_format", format: "json", message: err.message }); return z.NEVER; } }, encode: (value) => JSON.stringify(value), });

总结

需求用这个
数据进来时转换 + 校验decode()(等价于parse()
数据出去时序列化encode()
反向 codecz.invertCodec()
不想抛异常safeDecode()/safeEncode()
字符串布尔值z.stringbool()

Zod Codecs 的核心理念:一份 schema,双向转换,客户端和服务器共用。掌握z.codec()的两行基本语法 + encode 方向的规则细节,就能覆盖 90% 的场景。更多 API 细节可查阅官方文档 packages/docs/content/codecs.mdx,核心实现位于 packages/zod/src/v4/core/schemas.ts。

【免费下载链接】zodTypeScript-first schema validation with static type inference项目地址: https://gitcode.com/GitHub_Trending/zo/zod

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/3 12:01:21

学习机芯片解析:从RK3399到RK3588,作业帮学习机的硬件底牌

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/3 12:01:16

MATLAB实现BiLSTM多特征时序分类:从原理到工程实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/3 11:58:52

Windows下AI开发为何首选WSL2:从架构到GPU与Docker全解析

如果你现在还在 Windows 原生环境下跑 AI 开发&#xff0c;大概率是这类体验&#xff1a;装 Python 依赖时总有包编译不过去&#xff0c;明明 ChatGPT / Claude / 各种 Client 用得很顺&#xff0c;一到本地跑模型就各种报错。很多人以为这是电脑配置不够&#xff0c;或者提示词…

作者头像 李华
网站建设 2026/9/3 11:55:32

Windows 部署 Hermes Agent 步骤繁琐?一键整合包快速完成本地搭建

Windows 本地部署 Hermes 太麻烦&#xff1f;这个一键包 5 分钟就能跑起来 很多人想体验 Hermes Agent&#xff0c;但真正开始部署时&#xff0c;往往会卡在环境配置上。 要装依赖、配运行环境、处理路径问题&#xff0c;还可能遇到命令行报错、系统拦截、文件缺失等情况。对…

作者头像 李华