# UnionSchema _(no submodules)_ ## Purpose `UnionSchema` validates that an input satisfies at least one of a list of member schemas. It short-circuits on the first successful parse, returning that result without checking remaining members. When all members fail, it aggregates all their issues into the `ValidationError`, giving the caller visibility into why each arm failed. ## Features - Short-circuit success: first matching schema wins - All-failure aggregation: every arm's issues collected into one `ValidationError` - Empty union: always fails with `VALIDATION.UNION.NO_MATCH` ## Usage: Basic Example ```typescript import { union, string, number } from "@suaveplan/validation"; const stringOrNumber = union([string(), number()]); stringOrNumber.parse("hello"); // "hello" stringOrNumber.parse(42); // 42 stringOrNumber.parse(true); // throws ValidationError ``` ## Usage: Advanced Example ```typescript import { union, literal, object, string } from "@suaveplan/validation"; // Discriminated union const Event = union([ object({ type: literal("created"), id: string() }), object({ type: literal("deleted"), id: string(), reason: string() }), ]); Event.parse({ type: "created", id: "abc" }); // { type: "created", id: "abc" } ``` ## API Reference ### `union(schemas: AnySchema[]): UnionSchema` Factory accepting an array of member schemas. ### `_parse(input, ctx): unknown | INVALID` Iterates schemas in order. Returns the first non-`INVALID` result. On all-failure, pushes all collected issues to `ctx.issues` and returns `INVALID`. Empty union always adds a single `VALIDATION.UNION.NO_MATCH` issue. ## Implementation Notes - Each arm runs with its own `childCtx` so its issues don't contaminate the parent context until the all-failure path is confirmed. - The order of schemas matters: place more specific schemas first to avoid false positives from permissive schemas like `string()`. - The aggregated issue list can be long for wide unions; callers may want to use `flatten()` to extract meaningful field-level errors. ### Parse Behaviour `z.union([a, b, c])` tries each member in order and returns the first success; all failures are aggregated into a `ZodUnionError` with per-member diagnostics so callers can show a useful error. For discriminated unions (a shared literal key across members), prefer `z.discriminatedUnion("kind", [...])` which is faster and produces cleaner errors.