我正在制作与我同事类似的表格,但有一些额外的字段。我已经获取了他的 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),
})
Run Code Online (Sandbox Code Playgroud)
他有很多refine调用链接到他的车辆对象,如下所示:
.refine((data) => isUnique(data.name), {
message: 'Characters must be unique',
})
Run Code Online (Sandbox Code Playgroud)
我需要能够捆绑这些精炼链并在两个 zod 对象上使用它们。
确切地说最好的方法是什么有点困难,因为我认为有几种选择。
首先,我建议尽可能将改进保留在其适用的领域。例如,refine我不会调用整个对象,而是调用refineforz.string()字段name:
export const vehicleZodObject = z.object({
name: z.string().refine(isUnique, { message: 'Characters must be unique' },
engine: type: z.enum(['electric', 'combustion']),
});
Run Code Online (Sandbox Code Playgroud)
接下来,可以定义一个辅助函数,对其所传递的模式进行细化。您可以使用两个模式共享的接口进行设置,然后调用所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()
})
);
Run Code Online (Sandbox Code Playgroud)
即使在这种情况下,我建议创建一个base仅包含字段a和 的模式b,仅将细化添加到base模式中,然后构建schema1并schema2使用z.intersection. 这符合细化尽可能靠近其应用的地方的原则。
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()
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15326 次 |
| 最近记录: |