TypeScript 数据验证:Zod、Yup 和 io-ts 库概览
TypeScript 是一种静态类型语言,它在编译阶段检查类型。然而,在运行时(runtime),TypeScript 不执行任何检查。这意味着来自外部来源的数据——如 API 请求、输入表单、配置文件——可能不符合预期的类型。为了解决这个问题,我们使用数据验证库,它们在运行时检查数据的结构和类型。
在本文中,我们将介绍三种流行的 TypeScript 数据验证库:Zod、Yup 和 io-ts。您将了解它们的工作原理、差异以及如何为您的项目选择合适的库。
为什么需要在 TypeScript 中进行数据验证?
假设您正在编写一个通过表单接收用户数据的应用程序:
interface UserInput { name: string; age: number; email: string;}
function processUserInput(input: UserInput) { console.log(input.name.toUpperCase());}在 TypeScript 中,即使运行时 input.name 是 undefined 或数字,这段代码也能编译通过。这会导致难以捕获的错误。验证库可以确保数据符合预期的模式,并提供清晰的错误信息。
Zod — 现代且快速的库
Zod 是一个用于声明式验证和类型推断的库。它专为 TypeScript 设计,并提供简洁的 API。
安装:
npm install zod使用示例:
import { z } from 'zod';
// 定义验证模式const UserSchema = z.object({ name: z.string().min(2, "姓名至少需要2个字符"), age: z.number().int().positive("年龄必须为正数"), email: z.string().email("邮箱格式不正确"),});
// 基于模式推断类型type User = z.infer<typeof UserSchema>;
// 数据验证const result = UserSchema.safeParse({ name: "安娜", age: 25, email: "anna@example.com",});
if (result.success) { // result.data 的类型为 User console.log(result.data.name);} else { // result.error 包含详细的错误信息 console.error(result.error.format());}Zod 支持复杂结构:嵌套对象、数组、联合类型、可区分联合。它还可以转换数据(例如,将字符串转换为数字)。
Yup — 来自 React 生态系统的流行库
Yup 是一个模式验证库,广泛与 Formik 一起用于 React 应用程序。它的 API 与 Zod 类似,但出现得更早。
安装:
npm install yup使用示例:
import * as yup from 'yup';
// 定义模式const userSchema = yup.object({ name: yup.string().min(2, "姓名至少需要2个字符").required(), age: yup.number().integer().positive().required(), email: yup.string().email("邮箱格式不正确").required(),});
// 使用 validate 方法进行验证userSchema.validate({ name: "伊万", age: 30, email: "ivan@example.com",}).then(validData => console.log(validData)).catch(err => console.error(err.errors));Yup 提供了便捷的表单验证方法,支持自定义错误消息和条件规则(when)。然而,它与 TypeScript 的集成不如 Zod 紧密——类型推断需要额外的操作。
io-ts — 函数式验证方法
io-ts 是一个基于函数式编程的库。它使用编解码器(codecs)的概念来进行转换