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

如何用Zod验证email与reemail字段值一致?

Zod 实现邮箱重复验证的方案

方法一:修复你的 superRefine 写法

你的代码逻辑本身是正确的,大概率是验证触发方式的问题导致没生效。确保你通过 parse 或 safeParse 方法执行验证,以下是完整可运行的示例:

import { z } from "zod";

export const validationSchema = z.object({
    email: z.string().email({ message: "请输入有效的邮箱地址。" }).min(1, "此字段为必填项。"),
    reemail: z.string().min(1, "此字段为必填项。"),
}).superRefine((data, ctx) => {
    if (data.email !== data.reemail) {
        ctx.addIssue({
            code: z.ZodIssueCode.custom,
            message: "两次输入的邮箱不匹配。",
            path: ["reemail"] // 将错误标记在重复输入的邮箱字段上
        });
    }
});

// 验证测试
const validInput = { email: "test@example.com", reemail: "test@example.com" };
console.log(validationSchema.safeParse(validInput)); // 输出成功结果

const invalidInput = { email: "test@example.com", reemail: "wrong@example.com" };
console.log(validationSchema.safeParse(invalidInput)); // 输出包含reemail字段错误的结果

方法二:字段内直接依赖验证(更简洁)

如果你想贴近 Yup oneOf 的使用习惯,可以在 reemail 字段内直接引用 email 的值,无需用到 superRefine:

方式1:使用 refine 结合父级字段

import { z } from "zod";

export const validationSchema = z.object({
    email: z.string().email({ message: "请输入有效的邮箱地址。" }).min(1, "此字段为必填项。"),
    reemail: z.string()
        .min(1, "此字段为必填项。")
        .refine((val, ctx) => val === ctx.parent.email, {
            message: "两次输入的邮箱不匹配。"
        })
});

方式2:使用 oneOf + z.lazy(贴近Yup写法)

通过 z.lazy 解决循环引用问题,让 reemail 匹配 email 的值:

import { z } from "zod";

export const validationSchema = z.object({
    email: z.string().email({ message: "请输入有效的邮箱地址。" }).min(1, "此字段为必填项。"),
    reemail: z.string()
        .min(1, "此字段为必填项。")
        .oneOf([z.lazy(() => validationSchema.shape.email)], {
            message: "两次输入的邮箱不匹配。"
        })
});

方案对比

  • superRefine 适合多字段联动验证、需要添加多个自定义错误的复杂场景;
  • 字段内的 refine 写法更简洁,适合单一字段依赖父级字段的简单验证;
  • oneOf + z.lazy 的写法最贴近你之前使用 Yup 的习惯,逻辑直观。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 20:36:10