3.4 Union Types

Union types represent values that may have one of several distinct representations. A value of a union type A | B is a value that is either of type A or type B. Union types are written using union type literals (section 3.8.6).

A union type encompasses an ordered set of constituent types. While it is generally true that A | B is equivalent to B | A, the order of the constituent types may matter when determining the call and construct signatures of the union type.

Union types have the following subtype relationships:

  • A union type U is a subtype of a type T if each type in U is a subtype of T.
  • A type T is a subtype of a union type U if T is a subtype of any type in U.

Similarly, union types have the following assignability relationships:

  • A union type U is assignable to a type T if each type in U is assignable to T.
  • A type T is assignable to a union type U if T is assignable to any type in U.

The || and conditional operators (section 4.19.7 and 4.20) may produce values of union types, and array literals (section 4.6) may produce array values that have union types as their element types.

Type guards (section 4.24) may be used to narrow a union type to a more specific type. In particular, type guards are useful for narrowing union type values to a non-union type values.

In the example

  1. var x: string | number;
  2. var test: boolean;
  3. x = "hello"; // Ok
  4. x = 42; // Ok
  5. x = test; // Error, boolean not assignable
  6. x = test ? 5 : "five"; // Ok
  7. x = test ? 0 : false; // Error, number | boolean not assignable

it is possible to assign ‘x’ a value of type string, number, or the union type string | number, but not any other type. To access a value in ‘x’, a type guard can be used to first narrow the type of ‘x’ to either string or number:

  1. var n = typeof x === "string" ? x.length : x; // Type of n is number

For purposes of property access and function calls, the apparent members (section 3.11.1) of a union type are those that are present in every one of its constituent types, with types that are unions of the respective apparent members in the constituent types. The following example illustrates the merging of member types that occurs when union types are created from object types.

  1. interface A {
  2. a: string;
  3. b: number;
  4. }
  5. interface B {
  6. a: number;
  7. b: number;
  8. c: number;
  9. }
  10. var x: A | B;
  11. var a = x.a; // a has type string | number
  12. var b = x.b; // b has type number
  13. var c = x.c; // Error, no property c in union type

Note that ‘x.a’ has a union type because the type of ‘a’ is different in ‘A’ and ‘B’, whereas ‘x.b’ simply has type number because that is the type of ‘b’ in both ‘A’ and ‘B’. Also note that there is no property ‘x.c’ because only ‘B’ has a property ‘c’.

When used as a contextual type (section 4.23), a union type has those members that are present in any of its constituent types, with types that are unions of the respective members in the constituent types. Specifically, a union type used as a contextual type has the apparent members defined in section 3.11.1, except that a particular member need only be present in one or more constituent types instead of all constituent types.