API reference@evolu/commonType › union

Call Signature

function union<Expected>(
  ...expected: {
    readonly [Index in string | number | symbol]: ValidateLiteral<
      Expected[Index]
    >;
  }
): UnionType<{
  readonly [Index in string | number | symbol]: LiteralType<Expected[Index]>;
}>;

Defined in: packages/common/src/Type.ts:3975

Union Type.

Use union(A, B) when a value may match any one of several Types. Literal values can be passed directly as shorthand for their corresponding Literal Types.

For Object variants with a required literal discriminator, use discriminatedUnion. It selects the matching member by its discriminator instead of trying every member.

fromUnknown tries each member's complete pipeline in argument order and returns the first successful result. from accepts the Union Output. from.parent accepts a root member Output, selects members whose root is accepts the value, and runs their remaining stages on the original typed value.

If every member fails, the error identifies each retained failure by its member index. By default, only the first member failure is retained. Pass { errors: "all" } to retain every member failure and collect nested errors within each member.

Formatting keeps one Union issue at the enclosing path and appends the retained failures below its summary. Member indexes identify alternatives, not positions in the input. Nested member paths appear in the message. Formatting never retries validation or recovers discarded failures.

Member order matters when multiple members accept the same value: validation and encoding use the first matching member. When member Inputs overlap, decoding the value emitted by the first member selected for an Output must reproduce that semantic Output; otherwise the Union violates the round-trip law.

Example

import {
  assertEqual,
  assertErr,
  assertOk,
  assertType,
  Data,
  Number,
  String,
  union,
} from "@evolu/common";

const Status = union("draft", "published");
const StatusOrCode = union("draft", "published", Number);

assertOk(Status.fromUnknown("draft"), "draft");
assertOk(StatusOrCode.fromUnknown(42), 42);

const TextOrNumber = union(String, Number);

const invalid = TextOrNumber.fromUnknown(true, { errors: "all" });
assertErr(invalid);
assertType(Data, invalid.error);
assertEqual(invalid.error, {
  type: "Union",
  errors: [
    {
      index: 0,
      error: { type: "TypeOf", expected: "String", value: true },
    },
    {
      index: 1,
      error: { type: "TypeOf", expected: "Number", value: true },
    },
  ],
});

Call Signature

function union<Members>(
  ...members: {
    readonly [Index in string | number | symbol]: ValidateUnionTypeMember<
      Members[Index]
    >;
  }
): UnionType<Members>;

Defined in: packages/common/src/Type.ts:3984

Creates a Union Type from Type members.

Call Signature

function union<Members>(
  ...members: {
    readonly [Index in string | number | symbol]: ValidateUnionMember<
      Members[Index]
    >;
  }
): UnionType<NormalizeUnionMembers<Members>>;

Defined in: packages/common/src/Type.ts:3991

Creates a Union Type from Type and literal members.