为何 Zod 能成为 TypeScript 优先的数据验证顶流?

家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!

什么是 Zod

TypeScript-first schema validation with static type inference

Zod 是一个 TypeScript 优先的 schema 声明和验证库,支持从简单的字符串到复杂的嵌套对象。Zod 的设计尽可能方便开发人员使用,目标是消除重复的类型声明。使用 Zod,开发者只需声明一次验证器,Zod 就会自动推断静态 TypeScript 类型,从而简化简单类型组合成复杂的数据结构的过程。

Zod 的特点包括:

  • 零依赖性、适用于 Node.js 和所有现代浏览器
  • 体积微小:8kb 最小化 + 压缩
  • 不可变:方法(例如 .optional())返回一个新实例,简洁、可链接的接口
  • 函数式方法:解析,不验证
  • 同样适用于纯 JavaScript

目前 Zod 在 Github 通过 MIT 协议开源,有超过 31.6k 的 star、1.1k 的 fork、代码贡献者 300+、妥妥的前端优质开源项目。

如何使用 Zod

Zod 支持 TypeScript 4.5+,同时开发者必须在 tsconfig.json 中启用严 schema,这也是所有 TypeScript 项目的最佳实践。

// tsconfig.json
{
  // ...
  "compilerOptions": {
    // ...
    "strict": true
  }
}

然后可以通过下面命令安装:

npm install zod       # npm
yarn add zod          # yarn
bun add zod           # bun
pnpm add zod          # pnpm
import {z} from "https://deno.land/x/zod/mod.ts";
// deno

下面是 Zod 的简单示例:

import {z} from "zod";
// creating a schema for strings
const mySchema = z.string();
// parsing
mySchema.parse("tuna"); // => "tuna"
mySchema.parse(12); // => throws ZodError
// "safe" parsing (doesn't throw error if validation fails)
mySchema.safeParse("tuna"); // => { success: true; data: "tuna" }
mySchema.safeParse(12); // => { success: false; error: ZodError }

下面是对 Object 进行验证的示例:

import {z} from "zod";

const User = z.object({
  username: z.string(),
});

User.parse({username: "Ludwig"});

// extract the inferred type
type User = z.infer<typeof User>;
// {username: string}

Zod 枚举是定义和验证枚举的推荐方法。但是,如果开发者需要针对第三方库中的枚举进行验证(或者您不想重写现有枚举),可以使用 z.nativeEnum()。

enum Fruits {
  Apple,
  Banana,
}

const FruitEnum = z.nativeEnum(Fruits);
type FruitEnum = z.infer<typeof FruitEnum>; // Fruits

FruitEnum.parse(Fruits.Apple); // passes
FruitEnum.parse(Fruits.Banana); // passes
FruitEnum.parse(0); // passes
FruitEnum.parse(1); // passes
FruitEnum.parse(3); // fails

开发者还可以使用 .extend 方法向对象 schema 添加其他字段:

const DogWithBreed = Dog.extend({
  breed: z.string(),
});

默认情况下,Zod 对象 schema 会在解析过程中剔除无法识别的键,开发者可以使用 .strict() 禁止未知密钥。如果输入中有任何未知的键,Zod 将抛出错误。

const person = z
  .object({
    name: z.string(),
  })
  .strict();

person.parse({
  name: "bob dylan",
  extraKey: 61,
});
// => throws ZodError

在错误处理方面,Zod也足够优秀。Zod 提供了一个 Error 的子类,称为 ZodError, ZodErrors 包含一个 issues 数组,其中包含有关验证问题的详细信息:

const result = z
  .object({
    name: z.string(),
  })
  .safeParse({ name: 12 });

if (!result.success) {
  result.error.issues;
  /* [
      {
        "code": "invalid_type",
        "expected": "string",
        "received": "number",
        "path": [ "name" ],
        "message": "Expected string, received number"
      }
  ] */
}

更多关于 Zod 的用法和示例可以参考文末资料,本文不再过多展开。

参考资料

https://zod.dev/?id=introduction

https://zod.dev/?id=requirements

https://medium.com/@xsankalp13/zod-simplifying-validation-in-typescript-3486aeb402d8

https://isamatov.com/typescript-schema-validation-with-zod/

原文链接:,转发请注明来源!