Valibot 数据校验完全指南
Valibot 是模块化设计的轻量校验库:Tree-shaking 友好、类型推导完整。本文讲解 Schema 定义、错误处理与校验服务封装。
Valibot 用函数式 Schema:v.object({ email: v.pipe(v.string(), v.email()) }),v.parse 校验、InferInput 推导类型。相比 Zod 的核心优势:模块化设计让打包体积按用到的函数计——浏览器端可小至 1KB 级。
快速上手
npm install valibot
import * as v from 'valibot';
const UserSchema = v.object({
name: v.pipe(v.string(), v.minLength(1)),
email: v.pipe(v.string(), v.email()),
age: v.optional(v.pipe(v.number(), v.minValue(0))),
});
// 校验
const result = v.safeParse(UserSchema, data);
if (result.success) {
result.output; // 精确类型
} else {
result.issues; // 结构化错误列表
}
pipe 是 Valibot 的签名风格:v.pipe(v.string(), v.email()) 把"类型 + 校验规则"串成管道。
错误处理
const [error, output] = v.safeParse(UserSchema, data)
? [null, result.output] : [result.issues, null];
// issues 含 path/message——映射为表单错误
for (const issue of result.issues ?? []) {
console.log(issue.path?.map(p => p.key).join('.'), issue.message);
}
校验服务封装
// 把校验收敛为应用内的统一入口
export function validate<T extends v.GenericSchema>(schema: T, data: unknown) {
const result = v.safeParse(schema, data);
if (!result.success) {
throw new ValidationError(result.issues);
}
return result.output as v.InferOutput<T>;
}
// 业务层
const user = validate(UserSchema, req.body);
TypeScript 集成
v.InferInput/v.InferOutput 推导类型(有默认值/转换时输入输出类型不同——这是 Valibot 的精细处)。React Hook Form 有官方 resolver。
常见问题(FAQ)
Q:Valibot 和 Zod 怎么选?
浏览器端体积敏感选 Valibot(模块化 tree-shaking);生态集成广度选 Zod。API 能力两者相当,迁移成本低。
Q:v.parse 和 v.safeParse?
parse 不符即抛错(异常流);safeParse 返回结果对象(值流)。API 边界用 safeParse,信任数据用 parse。
Q:自定义校验规则?
v.check/v.custom 接任意谓词;复用逻辑封装为自定义 action 函数——Valibot 的模块化让扩展与内置同构。
参考文档
本文依据公开文档整理,示例需按项目依赖版本验证;不将文档中的性能描述视为本项目实测结果。