我有像这样的对象模式验证(简化):
因此,假设如果 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'],
});
}
});
我最近遇到了类似的挑战,想分享我使用
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
的值轻松定义有条件必需的字段的验证规则。