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

如何在Zod Schema中自定义数字校验的错误提示?

解决Zod + React Hook Form数字输入框空值错误提示问题

问题核心在于你设置了{ valueAsNumber: true },输入框为空时React Hook Form会把空值转为NaN,而Zod的z.number()校验失败时会抛出默认的「Expected number, received NaN」错误,且z.number()本身不支持直接传入自定义错误消息。

这里提供两种简洁的解决方式:

方法一:使用z.coerce.number()(推荐)

z.coerce.number()会自动尝试将输入值转为数字,同时支持通过invalid_type_error参数自定义类型转换失败时的错误提示,完美覆盖空值转NaN的场景。

修改后的Zod Schema代码:

import { z } from "zod";

export const newTransactionSchema = z.object({
  title: z
    .string()
    .min(1, "Title Must Be Atleast 1 Character")
    .max(10, "Title Must Be No Longer Than 10 Characters"),
  // 替换原number()为coerce.number()并设置自定义错误
  amountSpent: z.coerce.number({
    invalid_type_error: "请输入有效的金额数字", // 空值时的自定义提示
  }).positive("Please Enter An Expense Greater Than 0"),
  description: z
    .string()
    .min(8, "Description Must Be At Least 8 Characters")
    .max(25, "Description Must Be No Longer Than 25 Characters"),
});

export type TNewTransaction = z.infer<typeof newTransactionSchema>;

输入框代码可保持不变,也可以去掉valueAsNumber: true(因为coerce.number()已处理类型转换):

<label htmlFor="amountSpent">Amount Spent</label>
<input
  type="number"
  className="mt-2 rounded-md border border-[#3a3a3a] bg-[#0A0A0A] px-2 py-1 text-white outline-none focus:border-[#3a3a3a] focus:ring-2 focus:ring-[#3a3a3a] focus:ring-offset-2 focus:ring-offset-black"
  id="amountSpent"
  {...register("amountSpent")} // 可去掉valueAsNumber配置
/>
<span className="mb-3 font-medium text-rose-500">
  {errors?.amountSpent?.message}
</span>

方法二:预处理空值 + 自定义校验

如果不想用coerce,可以通过z.preprocess先把空值转为undefined,再结合refine强制要求输入值存在:

amountSpent: z.preprocess(
  (val) => {
    // 空字符串转为undefined
    if (val === "") return undefined;
    // 其他值尝试转换为数字
    return Number(val);
  },
  z.number()
    .positive("Please Enter An Expense Greater Than 0")
    .optional()
    .refine((val) => val !== undefined, "请输入金额")
)

这种方式稍显繁琐,但适合需要更复杂预处理逻辑的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 16:23:24