您可以使用superRefine
方法来指定类似这样的附加约束,也可以在本例中使用discriminatedUnion
,最终得到略微更强的类型.
超级精细化方法:
const formSchema = z
.object({
cli_rut: z.string(),
cli_persona_natural: z.enum(["SI", "NO"]),
cli_nombres: z.string().optional(),
cli_apellido_paterno: z.string().optional(),
cli_apellido_materno: z.string().optional(),
cli_razon_social: z.string().optional(),
cli_estado: z.string().default("ACTIVO").optional(),
})
.superRefine((data, ctx) => {
if (data.cli_persona_natural === "SI") {
if (data.cli_nombres === undefined) {
// I took a best guess at the messages but it's not my native language
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: "El campo nombres es requerido",
});
}
if (data.cli_apellido_paterno === undefined) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: "El campo apellido paterno es requerido",
});
}
if (data.cli_apellido_materno === undefined) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: "El campo apellido materno es requerido",
});
}
}
});
歧视并集方法
import { z } from "zod";
const baseSchema = z.object({
cli_rut: z.string(),
cli_razon_social: z.string().optional(),
cli_estado: z.string().default("ACTIVO").optional(),
});
const personaNaturalSchema = z.object({
cli_persona_natural: z.literal("SI"),
cli_nombres: z.string(),
cli_apellido_paterno: z.string(),
cli_apellido_materno: z.string(),
});
// Again no clue if this naming makes sense in practice
const personaJuridicaSchema = z.object({
cli_persona_natural: z.literal("NO"),
cli_nombres: z.string().optional(),
cli_apellido_paterno: z.string().optional(),
cli_apellido_materno: z.string().optional(),
});
const formSchema = z
.discriminatedUnion("cli_persona_natural", [
personaNaturalSchema,
personaJuridicaSchema,
])
.and(baseSchema);
console.log(
formSchema.safeParse({
cli_persona_natural: "SI",
cli_rut: "12345678",
cli_nombres: "John",
cli_apellido_paterno: "Steve",
cli_apellido_materno: "Tessa",
})
); // success
console.log(
formSchema.safeParse({
cli_persona_natural: "NO",
cli_rut: "12345678",
})
); // success
console.log(
formSchema.safeParse({
cli_persona_natural: "SI",
cli_rut: "12345678",
})
); // failure
这种方法对类型有好处.如果判断值cli_persona_natural
,则会得到关于其他字段是否必需的类型推断.