TypeScript 数据验证:工具与实践概述
在现代 TypeScript 网页开发中,关键任务之一是确保数据的完整性。即使 TypeScript 具有严格的静态类型化,它也无法保证来自外部世界(API、表单、localStorage)的数据符合预期格式。这时,运行时验证——在程序执行期间检查数据——就派上了用场。在本文中,我们将介绍三个流行的库:Zod、Yup 和 Joi,比较它们的方法,并展示如何将验证集成到 TypeScript 项目中。
为什么简单的 TypeScript 类型不够用?
TypeScript 在编译时检查类型,但在运行时所有注解都会被擦除。这意味着:
- 用户数据可能包含多余字段或缺少必填字段
- 数字可能以字符串形式传入
- 对象可能为
null或undefined
验证库通过提供既可作为检查又可作为类型推断的模式来解决此问题。
1. Zod——现代标准
Zod 是 TypeScript 中最流行的验证库。其主要优势是从模式自动推断 TypeScript 类型。
安装
npm install zod基本模式示例
import { z } from 'zod';
const UserSchema = z.object({ id: z.number().positive(), name: z.string().min(2).max(50), email: z.string().email(), age: z.number().int().min(18).optional(),});
// 类型推断:{ id: number; name: string; email: string; age?: number }type User = z.infer<typeof UserSchema>;
// 验证const result = UserSchema.safeParse(inputData);if (!result.success) { console.error(result.error.errors);} else { // result.data — 类型为 User 的正确数据 processUser(result.data);}高级功能
- 转换:
z.string().transform(val => val.trim()) - 判别联合:
z.discriminatedUnion('type', [...]) - 递归模式:
z.lazy(() => NodeSchema) - 自定义错误:
z.string().refine(val => !val.includes('bad'), '不能使用 bad 这个词')
2. Yup——久经考验的工具
Yup 是一个历史悠久的库,最初为表单验证而创建。它与 Formik 和 React Hook Form 集成良好。
安装
npm install yup模式示例
import * as yup from 'yup';
const productSchema = yup.object({ title: yup.string().required('标题必填').min(3), price: yup.number().positive('价格必须为正数').required(), inStock: yup.boolean().default(true),});
type Product = yup.InferType<typeof productSchema>;
// 验证productSchema.validate(inputData, { abortEarly: false }) .then(validData => console.log(validData)) .catch(err => console.error(err.errors));Yup 的特点
- 支持条件验证:
.when('field', ...) - 内置错误消息(配置区域设置后)
- 轻松处理嵌套对象和数组
- 用于类型转换的
cast()和transform()方法
3. Joi——功能强大但更重
Joi 是来自 Node.js 生态系统(Hapi.js)的传奇库。它提供了最大的灵活性,但没有内置的 TypeScript 集成(需要手动定义类型)。
安装
npm install joi @types/joi<