Capítulo 20 de 61
z.discriminatedUnion() is a faster, more precise union for the common case where every option is an object sharing one literal "tag" field; z.intersection() represents a logical AND of two schemas.
z.discriminatedUnion(key, [...objectSchemas]): each option must be an object schema whose key property is a literal (or z.enum()/z.literal()/z.null()/z.undefined()) — Zod uses the discriminator value to jump straight to the matching option instead of trying each one in order, which is both faster and gives better error messages than a naive z.union().z.intersection(a, b): the parsed value must satisfy both schemas simultaneously; for primitive unions this narrows to their common members (e.g. intersecting number | string with number | boolean infers just number).const MyResult = z.discriminatedUnion("status", [
z.object({ status: z.literal("success"), data: z.string() }),
z.object({ status: z.literal("failed"), error: z.string() }),
]);
// nested discriminated unions
const MyErrors = z.discriminatedUnion("code", [
z.object({ status: z.literal("failed"), code: z.literal(400) }),
z.object({ status: z.literal("failed"), code: z.literal(401) }),
]);
const Combined = z.discriminatedUnion("status", [
z.object({ status: z.literal("success"), data: z.string() }),
MyErrors,
]);
const a = z.union([z.number(), z.string()]);
const b = z.union([z.number(), z.boolean()]);
const c = z.intersection(a, b); // inferred type: number
z.union() for a large set of object variants with a shared tag field: it's slower (checks every option in order) and gives worse error messages than z.discriminatedUnion(), which can jump straight to the right branch.z.discriminatedUnion() — it's strictly better than z.union() for that shape.z.intersection() is for combining independent constraints (AND), not for merging object shapes — use .extend() or object spread for that instead.