提问人:Емил Цоков 提问时间:10/26/2023 更新时间:10/27/2023 访问量:113
根据字段值更改 zod 架构对象的一部分?
Change part of zod schema object based on field value?
问:
我有一个带有一些字段的表单和一个开关,用于显示/隐藏表单的某些部分,如下所示:
<Field name="field1" value={value1} />
<Field name="field2" value={value2} />
<Switch value={showShippingAddress} / >
{ showShippingAddress && (
<>
<Field name="field3" value={value3} />
<Field name="field4" value={value4} />
</>
)}
在 zod 模式中,我想实现这样的事情
z
.object({
field1: z.string()
field2: z.string(),
showShippingAddress: z.boolean(),
field3: showShippingAddressValue ? z.required : z.string(), // wrong just for describing desired result
field4: showShippingAddressValue ? z.string.required.regex('') : z.string(), // also wrong
问题是我怎样才能以更好的方式做到这一点,比我目前能看到的唯一方式更好:
z
.object({
field1: z.string()
field2: z.string(),
})
.and(
z.object({
showShippingAddress: z.boolean(),
field3: z.string().nullable(),
field4: z.string().nullable(),
})
.superRefine(
({ showShippingAddress, field3, field4}, { addIssue }) => {
if(showShippingAddress && notEmptyCheckHelper(field3)) {
.addIssue({
code: z.ZodIssueCode.custom,
message: `Field3 is required.`
})
}
if(showShippingAddress && notEmptyCheckHelper(field4)) {
.addIssue({
code: z.ZodIssueCode.custom,
message: `Field4 is required.`
})
}
if(showShippingAddress && regexCheckHelper(field4)) {
.addIssue({
code: z.ZodIssueCode.custom,
message: `Field4 is not valid.`
})
}
// if there are more validations on Field 4 the checks here also grow and
// the same for more fields that depend on this showShippingAddress value
}))
答:
1赞
Sarath S Menon
10/27/2023
#1
受歧视的工会正是您正在寻找的。
您将需要 2 个对象,一个将 showShippingAddress 作为文本“true”,另一个将 showShippingAddress 作为文本“false”。然后进行歧视性结合。
所以在你的情况下,这样的事情应该有效
z.discriminatedUnion("showShippingAddressValue", [
z.object({
showShippingAddressValue: z.literal(false),
field1: z.string(),
field2: z.string(),
field3: z.string().optional(),
field4: z.string().optional()
}),
z.object({
showShippingAddressValue: z.literal(true),
field1: z.string(),
field2: z.string(),
field3: z.string(),
field4: z.string()
})
]);
请注意,仅使用即可使其成为必填字段,而添加 .optional() 将使该字段成为可选字段。z.string()
所以我上面提供的架构将成功解析:
final.parse({
showShippingAddressValue: false,
field1: "some value",
field2: "some value"
});
final.parse({
showShippingAddressValue: true,
field1: "some value",
field2: "some value",
field3: "some value",
field4: "some value"
});
但它将无法解析
final.parse({
showShippingAddressValue: true,
field1: "some value",
field2: "some value"
});
另外,还有一个额外的注意事项,如果您不希望字符串为空,则可能需要使用 .nonempty() 方法
评论
0赞
Емил Цоков
10/30/2023
zod.dev/?id=nonempty 是数组方法,而不是字符串方法
0赞
Sarath S Menon
10/30/2023
但它也适用于字符串,其他数组方法如 min、max 也适用于字符串
评论