如何在Zod中编写Refine规则:允许数值为null且非空时校验大小
解决Zod refine在字段为null时仍触发校验的问题
你的问题出在humidity和maxHumidity对应的refine逻辑上:当前条件只有当两个字段都不为null且humidity < maxHumidity时才返回true,而当其中一个或两个为null时,整个表达式会返回false,Zod会将false判定为校验失败,所以即使两个字段都是null也会触发错误提示。
要实现「仅当两个数值均不为null时才校验大小,否则允许为空」的需求,需要调整refine的逻辑:只要两个字段中有一个是null,就直接通过校验;只有当两个都有值时,才检查humidity是否小于maxHumidity。
修改后的完整代码如下:
type formData = { name: string; password: number; confirmPassword: number; humidity: number | null; maxHumidity: number | null; }; const schema: ZodType<formData> = z .object({ name: z.string().min(1).max(10), password: z.number().min(0).max(10), confirmPassword: z.number().min(0).max(10), humidity: z.number().min(0).max(10).nullable(), maxHumidity: z.number().min(0).max(10).nullable(), }) .refine((data) => data.password > data.confirmPassword, { message: "密码必须大于确认密码", path: ["password"], }) .refine( (data) => // 逻辑:要么至少一个字段为null(跳过校验),要么两个都有值且满足大小关系 (data.humidity === null || data.maxHumidity === null) || data.humidity < data.maxHumidity, { message: "最大湿度必须大于湿度", path: ["maxHumidity"], } ); const { register, handleSubmit, reset, formState: { errors }, } = useForm<formData>({ resolver: zodResolver(schema), defaultValues: { humidity: null, maxHumidity: null }, });
关键逻辑说明
- 新的refine条件拆为两部分:
(data.humidity === null || data.maxHumidity === null):只要其中一个字段为null,直接返回true,允许通过校验data.humidity < data.maxHumidity:只有当两个字段都不为null时,才执行大小校验,满足则返回true,否则返回false触发错误
另外顺便修正了你原代码里的错误提示文案(把“确认密码”改为“湿度”),避免混淆。
内容的提问来源于stack exchange,提问作者Zach philipp
相关产品推荐
相关产品推荐

