基于 Zod 中其他字段的必填字段

问题描述 投票:0回答:1

我有像这样的对象模式验证(简化):

因此,假设如果 is_change_part 值为 'Yes',我希望强制 barcode_old,并且默认情况下其为可选。

是的,我可以这样做:

const stringRequired = yup.string().required();

export const validation = yup.object().shape({
    serial_number: stringRequired,
    barcode_old: yup.string().when('is_change_part', {
         is: (isChangePart: string) => isChangePart === 'Yes',
         then: stringRequired,
    }),
    category: stringRequired,
    sub_category: stringRequired,
    is_change_part: stringRequired
)};

如何将其转换为 Zod?

我还是很困惑如何在Zod中做到这一点,我已经尝试过这样的方法,但仍然不起作用。

编辑:我找到了一种方法,但是还有更好的方法吗?

const stringRequired = z.string().min(1);

export const Schema = z
  .object({
    serial_number: stringRequired,
    barcode_old: z.string().optional(),
    is_change_part: stringRequired,
    category: stringRequired,
    sub_category: stringRequired,
  })
  .superRefine((val) => { 
    // make barcode_old mandatory if is_change_part === 'Yes'
    
    /* 
      This can work now, but is there a more concise and better 
      way? I think this is too verbose, I should check undefined 
      and addIssue()
    */

    if (val.is_change_part === 'Ya' && val.barcode_old === undefined) {
      ctx.addIssue({
        code: 'custom',
        message: 'mandatory',
        path: ['barcode_old'],
      });
    }
  
  });
javascript validation schema yup zod
1个回答
0
投票

我最近遇到了类似的挑战,想分享我使用

discriminatedUnion
想出的解决方案。

export const Schema = z.object({
  serial_number: stringRequired,
  barcode_old: z.string().optional(),
  is_change_part: z.enum(["Yes", "No"]),
  category: stringRequired,
  sub_category: stringRequired,
});

export const union = z.discriminatedUnion("is_change_part", [
  z.object({
    is_change_part: z.literal("Yes"),
    barcode_old: stringRequired,
  }),
  z.object({
    is_change_part: z.literal("No"),
  })
]);

通过此设置,您可以根据

is_change_part
的值轻松定义有条件必需的字段的验证规则。

© www.soinside.com 2019 - 2024. All rights reserved.