如何重新格式化Zod返回的Schema验证错误以包含无效输入值?
自定义Zod验证错误消息,包含无效输入值
当然可以,Zod提供了多种方式自定义错误消息,让你轻松把无效输入值包含在提示文本里,以下是几种常用方案:
1. 直接在Schema规则中自定义消息
针对内置验证规则(如min、max、email等),可以在规则配置的message字段里用${value}引用当前验证的输入值:
import { z } from "zod"; // 验证数字必须大于0 const positiveNumberSchema = z.number().min(1, { message: "Number must be greater than 0, but received: ${value}" }); // 测试无效输入 try { positiveNumberSchema.parse(-3); } catch (err) { if (err instanceof z.ZodError) { console.log(err.errors[0].message); // 输出:Number must be greater than 0, but received: -3 } }
2. 用refine实现自定义验证与错误消息
如果需要更复杂的验证逻辑,可以用refine方法,直接获取输入值并构造错误消息:
import { z } from "zod"; const positiveNumberSchema = z.number().refine( (val) => val > 0, // 自定义验证逻辑 (val) => ({ message: `Number must be greater than 0, but received: ${val}` }) ); // 测试无效输入 try { positiveNumberSchema.parse(-3); } catch (err) { if (err instanceof z.ZodError) { console.log(err.errors[0].message); // 输出:Number must be greater than 0, but received: -3 } }
3. 全局重写错误消息格式
如果想统一修改所有同类型验证的错误格式,可以用z.setErrorMap全局配置:
import { z } from "zod"; z.setErrorMap((issue, ctx) => { // 针对数字类型的"too_small"错误(即min验证失败) if (issue.code === z.ZodIssueCode.too_small && issue.type === "number") { return { message: `Number must be greater than ${issue.minimum}, but received: ${ctx.data}` }; } // 其他错误类型保留默认消息 return { message: ctx.defaultError }; }); // 使用默认min规则,错误消息会自动套用全局格式 const positiveNumberSchema = z.number().min(1); try { positiveNumberSchema.parse(-3); } catch (err) { if (err instanceof z.ZodError) { console.log(err.errors[0].message); // 输出:Number must be greater than 1, but received: -3 } }
注意事项
- 不同内置验证规则的错误模板中,
${value}是通用的占位符,可直接引用输入值; - 全局错误映射会影响所有Zod Schema的验证错误,适合需要统一风格的场景;
- 对于嵌套对象的验证,错误消息中同样可以通过
${value}获取对应字段的无效值。
内容的提问来源于stack exchange,提问作者Lemour
相关产品推荐
相关产品推荐

