使用 Zod 进行运行时校验
不要仅仅断言数据是某种类型,而要验证它确实符合该类型。
安装依赖
如果你在本地环境,需要先安装 Zod:
npm install zod示例程序
这个程序模拟了从 API 获取用户列表的过程,并处理了数据格式不匹配的情况。
import { z } from 'zod';
// --- 1. 定义数据 Schema ---
// 这不仅是类型,也是运行时的“安检站”
const UserSchema = z.object({
id: z.number(),
name: z.string(),
email: z.string().email(), // 甚至可以校验格式
website: z.string().url().optional(), // 可选字段且必须是 URL
});
// 使用 z.infer 自动导出 TypeScript 类型,无需重复定义 interface
type User = z.infer<typeof UserSchema>;
// --- 2. 封装通用的安全 Fetch 函数 ---
async function safeFetch<T>(
url: string,
schema: z.ZodSchema<T>
): Promise<T> {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const rawData = await response.json();
// 使用 .parse() 进行校验
// 如果数据不符合 Schema,这里会直接抛出详细的 ZodError
return schema.parse(rawData);
}
// --- 3. 实际调用示例 ---
async function main() {
try {
console.log("正在获取数据...");
// 假设这个 API 返回一个用户数组
const users = await safeFetch(
'https://jsonplaceholder.typicode.com/users',
z.array(UserSchema) // 动态组合 Schema
);
// 此时 users 的类型被自动推导为 User[]
console.log("验证通过!第一位用户是:", users[0].name);
} catch (error) {
if (error instanceof z.ZodError) {
// 如果后端改了字段名或删除了字段,这里会抓到非常详细的错误报告
console.error("数据格式校验失败:", error.errors);
} else {
console.error("网络或其他错误:", error);
}
}
}
main();校验的核心逻辑
在使用 Zod 之后,你的数据流会经历以下过程:
- 获取响应:从网络拿到原始的
unknown数据。 - Schema 过滤:Zod 会逐个字段检查类型、长度、格式。
- 转换/清洗:你可以配置 Zod 自动去除多余字段(
strip)或者转换数据类型。 - 安全输出:通过校验后,数据才会以确定的类型进入你的业务逻辑。
为什么这样做更安全?
| 特性 | 普通 Fetch + as T | Fetch + Zod 校验 |
|---|---|---|
| 后端字段缺失 | 前端运行时可能在访问 .name 时报错 undefined |
在 parse 阶段直接报错,明确指出哪个字段丢了 |
| 数据类型变更 | 编译通过,但逻辑可能出错(如:字符串相加变拼接) | 立即拦截,确保 number 字段一定是数字 |
| 脏数据 | 无能为力 | 可以过滤掉后端返回的冗余字段,保持对象整洁 |
使用 Zod 进行运行时校验
https://liuyuhe666.github.io/2026/04/03/使用-Zod-进行运行时校验/