我正在研究一种类似于我同事的表格,还有一些额外的领域。我已经取得了他的zodObject,并扩展了它的额外字段。
他正在使用大量的.refine调用来验证他的表单,但是我想包装这个逻辑并在我的表单上使用它。
提取逻辑的最佳方法是什么,这样我们都可以使用它?
例如,对车辆进行验证,并对汽车对象进行扩展:
export const vehicleZodObject = z.object({
name: z.string(),
engine: type: z.enum(['electric', 'combustion']),
})
export const carZodObject = vehicleObject.extend({
wheels: z.number().min(4),
})他有许多refine调用被链接到他的vehicle对象上,如下所示:
.refine((data) => isUnique(data.name), {
message: 'Characters must be unique',
})我需要能够捆绑这些精炼链,并在两个zod对象上使用它们。
发布于 2022-07-07 04:18:11
确切地说什么是最好的方法有点困难,因为我认为有几个选择。
首先,我建议将改进尽可能地局限于它们应用的领域。例如,与其对整个对象调用refine,不如在z.string()上为name字段调用name:
export const vehicleZodObject = z.object({
name: z.string().refine(isUnique, { message: 'Characters must be unique' },
engine: type: z.enum(['electric', 'combustion']),
});接下来,可以定义一个帮助函数,它将细化应用于它所传递的模式。您可以使用两个模式共享的接口来设置它,然后在提交的模式上调用refine函数:
import { z } from "zod";
interface IShared {
a: string;
b: string;
}
function attachRefinements<O extends IShared, T extends z.ZodTypeDef, I>(
schema: z.ZodType<O, T, I>
) {
return schema.refine((shared) => shared.a !== shared.b, {
message: "a and b must be unique"
});
}
const schema1 = attachRefinements(
z.object({
custom: z.boolean(),
a: z.string(),
b: z.string()
})
);
const schema2 = attachRefinements(
z.object({
a: z.string(),
b: z.string(),
special: z.number()
})
);即使在这种情况下,我也建议创建一个只有a和b字段的a模式,将细化添加到base模式中,然后使用z.intersection构建schema1和schema2。这与这样的原则是一致的,即细化尽可能接近它适用的地方。
const base = z.object({
a: z.string(),
b: z.string(),
}).refine((x) => x.a !== x.b, {
message: 'a and b must be unique',
});
const schema1 = z.intersection(base, z.object({
custom: z.boolean(),
});
const schema2 = z.intersection(base, z.object({
special: z.number()
});https://stackoverflow.com/questions/72867815
复制相似问题