提问人:SevenSouls 提问时间:5/27/2023 更新时间:11/17/2023 访问量:3674
Zod 验证架构使字段成为必需的字段,基于另一个数组字段
Zod validation schema make field required based on another array field
问:
我有一个带有数组字段和字符串字段的 Zod 验证架构:
const zodSchema = z.object({
goals: z.array(z.string()).nonempty("At least one goal is required"),
goals_other: z.string(),
});
如何使该字段仅在数组包含字符串“Other”时才必填?goals_other
goals
我尝试了如下所示的优化功能,但没有奏效
const zodSchema = z
.object({
goals: z.array(z.string()).nonempty("At least one goal is required"),
goals_other: z.string(),
})
.refine((data) => (data.goals.includes("Other") ? true : false), {
message: "Required, please specify other goals",
path: ["goals_other"],
});
任何帮助都是值得赞赏的!
答:
2赞
Souperman
5/27/2023
#1
有一种简单的方法可以获得所需的行为,假设如果字段中存在错误数据,则当未包含在列表中时,如果架构无法解析。我将首先展示这种方法:goals_other
'Other'
import { z } from "zod";
const zodSchema = z
.object({
goals: z.array(z.string()).nonempty("At least one goal is required"),
goals_other: z.string().optional() // optional to avoid failing when it's missing
})
.superRefine(({ goals, goals_other }, ctx) => {
// Here we add the extra check to assert the field exists when
// the "Other" goal is present.
if (goals.includes("Other") && goals_other === undefined) {
ctx.addIssue({
code: "custom",
message: "Required, please specify other goals",
path: ["goals_other"]
});
}
});
console.log(zodSchema.safeParse({
goals: ['test'],
})); // success
console.log(zodSchema.safeParse({
goals: ['Other'],
})); // failure
console.log(zodSchema.safeParse({
goals: ['Other'],
goals_other: 11,
})); // failure (because goals_other is not a string)
console.log(zodSchema.safeParse({
goals: ['Other'],
goals_other: 'test',
})); // success
但是IMO对此存在一个问题:
zodSchema.safeParse({
goals: ['test'],
goals_other: 11,
}); // Failure
这种解析尝试是失败的,因为该字段应该是 a 并且它得到了一个数字。如果你真的不关心这个字段,除非你的目标列表中有目标,那么你真正想要的是忽略这个字段,直到你找到另一个字符串,然后进行验证。goals_other
string | undefined
goals_other
"Other"
const zodSchema = z
.object({
goals: z.array(z.string()).nonempty("At least one goal is required"),
goals_other: z.unknown(),
})
.superRefine(({ goals, goals_other }, ctx) => {
if (goals.includes("Other")) {
if (goals_other === undefined) {
ctx.addIssue({
code: "custom",
message: "Required, please specify other goals",
path: ["goals_other"]
});
} else if (typeof goals_other !== 'string') {
ctx.addIssue({
code: 'custom',
message: 'expected a string',
path: ['goals_other'],
});
}
}
});
此架构将正确分析,但不会优化输出类型。 会有有点无益的类型。你可以用 a 中的类型断言来解决这个问题,但这感觉也有点尴尬。最好继续使用第一个架构,并接受当不存在该字段时,您实际上并没有忽略该字段。只要其他数据没有出现在您正在解析的值中,您就不会有问题。other_goals
unknown
transform
goals_other
"Other"
评论