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

如何让Zod表单验证的双可选输入项均显示错误提示?

解决方法

问题出在Zod的refine方法上——你虽然在path里写了两个字段,但Zod并不会自动给两个字段都挂载错误,只会把错误绑定到数组的最后一个元素(也就是sampleb)上,这就是为啥只有它显示错误。

要让两个输入框都触发错误提示,推荐用superRefine来手动给不符合条件的字段加错误:

const schema = z.object({
  samplea: z.string().optional(),
  sampleb: z.string().optional(),
}).superRefine((args, ctx) => {
  // 判断是否只填了其中一个字段
  const onlyOneFilled = (args.samplea && !args.sampleb) || (!args.samplea && args.sampleb);
  if (onlyOneFilled) {
    // 给samplea添加错误
    ctx.addIssue({
      code: z.ZodIssueCode.custom,
      message: "If you enter, please enter both",
      path: ["samplea"],
    });
    // 给sampleb添加错误
    ctx.addIssue({
      code: z.ZodIssueCode.custom,
      message: "If you enter, please enter both",
      path: ["sampleb"],
    });
  }
});

这样改完之后,只要只填了其中一个字段,samplea和sampleb的错误对象都会被赋值,对应的输入框就能各自显示错误提示了。

你也可以用两次refine来分别检查每个字段,虽然代码有点重复,但错误提示可以更精准:

const schema = z.object({
  samplea: z.string().optional(),
  sampleb: z.string().optional(),
})
// 检查samplea填了的话,sampleb必须填
.refine(args => !args.samplea || args.sampleb, {
  message: "If you enter samplea, you must enter sampleb",
  path: ["samplea"],
})
// 检查sampleb填了的话,samplea必须填
.refine(args => !args.sampleb || args.samplea, {
  message: "If you enter sampleb, you must enter samplea",
  path: ["sampleb"],
});

你的表单组件代码不用改,保持原来的错误判断和提示逻辑就行。

内容的提问来源于stack exchange,提问作者otera

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 11:58:31