使用 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 之后,你的数据流会经历以下过程:

  1. 获取响应:从网络拿到原始的 unknown 数据。
  2. Schema 过滤:Zod 会逐个字段检查类型、长度、格式。
  3. 转换/清洗:你可以配置 Zod 自动去除多余字段(strip)或者转换数据类型。
  4. 安全输出:通过校验后,数据才会以确定的类型进入你的业务逻辑。

为什么这样做更安全?

特性 普通 Fetch + as T Fetch + Zod 校验
后端字段缺失 前端运行时可能在访问 .name 时报错 undefined parse 阶段直接报错,明确指出哪个字段丢了
数据类型变更 编译通过,但逻辑可能出错(如:字符串相加变拼接) 立即拦截,确保 number 字段一定是数字
脏数据 无能为力 可以过滤掉后端返回的冗余字段,保持对象整洁

使用 Zod 进行运行时校验
https://liuyuhe666.github.io/2026/04/03/使用-Zod-进行运行时校验/
作者
Liu Yuhe
发布于
2026年4月3日
许可协议