如何将Yup的条件必填校验逻辑转换为Zod实现?
Zod实现条件必填字段的简洁方案
需求说明
当is_change_part的值为'Yes'时,barcode_old为必填项;默认情况下该字段为可选。
原Yup实现代码
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尝试(可行但繁琐)
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, ctx) => { // 当is_change_part为'Yes'时,barcode_old必填 if (val.is_change_part === 'Yes' && val.barcode_old === undefined) { ctx.addIssue({ code: 'custom', message: '必填项', path: ['barcode_old'], }); } });
更简洁的Zod实现方式
方式一:精简版refine写法(推荐)
这种写法最贴近Yup的when逻辑,把跨字段校验逻辑浓缩为一行:
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, }).refine( (val) => val.is_change_part !== 'Yes' || !!val.barcode_old, { message: '必填项', path: ['barcode_old'], } );
逻辑说明:当is_change_part不等于'Yes'时无需校验;如果等于'Yes',则barcode_old必须存在且不为空字符串(!!val.barcode_old和stringRequired的min(1)校验逻辑一致)。
方式二:联合类型拆分场景(更直观)
通过联合类型明确区分两种状态的结构,适合复杂多场景的校验需求:
const stringRequired = z.string().min(1, '必填项'); // 定义「更换部件」场景的schema const ChangePartYesSchema = z.object({ serial_number: stringRequired, barcode_old: stringRequired, is_change_part: z.literal('Yes'), category: stringRequired, sub_category: stringRequired, }); // 定义「不更换部件」场景的schema const ChangePartNoSchema = z.object({ serial_number: stringRequired, barcode_old: z.string().optional(), is_change_part: z.string().not(z.literal('Yes')), category: stringRequired, sub_category: stringRequired, }); export const Schema = z.union([ChangePartYesSchema, ChangePartNoSchema]);
这种写法能让校验逻辑更清晰,Zod会自动根据is_change_part的值匹配对应schema,错误提示也会更精准。
内容的提问来源于stack exchange,提问作者muhfaridzia
相关产品推荐
相关产品推荐

