next.js 如何在Zod中实现基于单选按钮选择的文件输入字段的条件验证?

1tu0hz3e  于 2023-11-18  发布在  其他
关注(0)|答案(1)|浏览(102)

我目前正在使用Zod和react hook表单进行表单验证,我面临着一个挑战,即基于单选按钮的选择来实现文件输入字段的条件验证。
下面是我的代码的简化版本:

const formScheme = z.object({
  businessType: z.enum(["PVT Ltd", "Partnership", "Sole Proprietor"], { required_error: 'Business Type is required.' }),
  form120: z
    .any()
    .optional()
    .refine(file => file.length == 1 ? file[0]?.type === 'application/pdf' ? true : false : true, 'Must be a PDF.')
    .refine(file => file.length == 1 ? file[0]?.size <= 3000000 ? true : false : true, 'Max file size is 3MB.'),
})

字符串
我想使form120字段仅在businessType为“PVT Ltd”时为必填字段。换句话说,如果用户选择“PVT Ltd”作为业务类型,则他们还必须使用form120字段上传文件。
我已经尝试了一些东西,但我不确定如何有条件地要求基于businessTypeform120字段。任何关于如何使用Zod实现这一点的建议或示例都将非常感谢。
提前感谢!

gjmwrych

gjmwrych1#

经过一些探索,我提出了一个解决方案,使用Zod和React Hook Forms来解决条件验证的挑战。如果你需要在businessType是“PVT Ltd”时才需要form120字段,你可以使用区分联合来实现这一点。

export const unionSchema = z.discriminatedUnion("businessType", [
  z.object({
    businessType: z.literal("PVT Ltd"),
    form120: z
      .any()
      .refine((file) => file?.length == 1, 'Form 1/20 is required for PVT Ltd business.')
      .refine((file) => file[0]?.type === 'application/pdf', 'Must be a PDF.')
      .refine((file) => file[0]?.size <= 5000000, `Max file size is 5MB.`),
  }),
  z.object({
    businessType: z.literal("Partnership"),
  }),
  z.object({
    businessType: z.literal("Sole Proprietor"),
  }),
]).and(formSchema)

字符串
在此模式中,我使用z.discriminatedUnion来处理基于businessType的不同验证规则。如果businessType是“PVT Ltd”,则会对form120字段强制执行特定的验证规则,使其成为必需字段并强制执行某些文件条件。对于其他业务类型(如“Partnership”和“Sole Proprietary”),不会应用任何额外的验证。

相关问题