[API reference](https://evolu.dev/docs/api-reference) › [@evolu/common](https://evolu.dev/docs/api-reference/common) › [Type](https://evolu.dev/docs/api-reference/common/Type) › union

## Call Signature

```ts
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:3579](https://github.com/evoluhq/evolu/blob/037c390af081e9944d616ff298a729515c5c5ab7/packages/common/src/Type.ts#L3579)

Union [Type](https://evolu.dev/docs/api-reference/common/Type/interfaces/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](https://evolu.dev/docs/api-reference/common/Type/interfaces/LiteralType).

For [Object variants](https://evolu.dev/docs/api-reference/common/Type/type-aliases/ObjectType) with a required literal
discriminator, use [discriminatedUnion](https://evolu.dev/docs/api-reference/common/Type/functions/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.

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

```ts
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

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

Defined in: [packages/common/src/Type.ts:3588](https://github.com/evoluhq/evolu/blob/037c390af081e9944d616ff298a729515c5c5ab7/packages/common/src/Type.ts#L3588)

Creates a Union Type from Type members.

## Call Signature

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

Defined in: [packages/common/src/Type.ts:3595](https://github.com/evoluhq/evolu/blob/037c390af081e9944d616ff298a729515c5c5ab7/packages/common/src/Type.ts#L3595)

Creates a Union Type from Type and literal members.