You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何重新格式化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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 22:12:22