求助:Zod中superRefine的校验问题无法通过自定义错误映射处理
Zod superRefine 错误映射不生效的解决方案
问题核心在于superRefine添加的校验问题未指定自定义code,导致全局/本地错误映射无法匹配对应规则。要让自定义校验错误走统一的错误映射,按以下步骤操作:
定义自定义错误code
给你的superRefine校验规则分配一个唯一的、有辨识度的code,比如custom_even_check、custom_password_strength这类名称。在superRefine中指定code
调用ctx.addIssue()时,明确传入这个自定义code,不要只写固定message。示例:
const numberSchema = z.number().superRefine((val, ctx) => { if (val % 2 !== 0) { ctx.addIssue({ code: "custom_even_check", // 关键:指定自定义code path: ctx.path, // 这里可以不写message,让错误映射接管消息生成 }); } });
- 在错误映射中配置对应消息
不管是全局错误映射还是本地parse时的错误映射,都要针对这个自定义code配置消息:
全局配置示例:
import { z } from "zod"; z.setErrorMap((issue, ctx) => { switch (issue.code) { // 处理Zod内置规则 case z.ZodIssueCode.too_small: return { message: "长度至少3位" }; // 处理自定义校验规则 case "custom_even_check": return { message: "必须是偶数" }; // 默认返回原错误消息 default: return { message: ctx.defaultError }; } });
本地parse配置示例(优先级高于全局):
try { numberSchema.parse(5, { errorMap: (issue, ctx) => { if (issue.code === "custom_even_check") { return { message: "本地规则:必须输入偶数" }; } return { message: ctx.defaultError }; }, }); } catch (err) { console.log(err.errors[0].message); // 输出"本地规则:必须输入偶数" }
原代码不生效的原因
你之前的superRefine可能是直接在addIssue里写死了message,或者用了默认的ZodIssueCode.custom但错误映射未匹配该code,导致消息无法被替换。通过指定自定义code并在映射中配置,就能让superRefine的错误和内置规则一样走统一的消息管理。
内容的提问来源于stack exchange,提问作者Ivan Čentš
相关产品推荐
相关产品推荐

