3.10 Type Aliases

A type alias declaration introduces a type alias in the containing declaration space.

  TypeAliasDeclaration:   typeBindingIdentifierTypeParametersopt=Type;

A type alias serves as an alias for the type specified in the type alias declaration. Unlike an interface declaration, which always introduces a named object type, a type alias declaration can introduce a name for any kind of type, including primitive, union, and intersection types.

A type alias may optionally have type parameters (section 3.6.1) that serve as placeholders for actual types to be provided when the type alias is referenced in type references. A type alias with type parameters is called a generic type alias. The type parameters of a generic type alias declaration are in scope and may be referenced in the aliased Type.

Type aliases are referenced using type references (3.8.2). Type references to generic type aliases produce instantiations of the aliased type with the given type arguments. Writing a reference to a non-generic type alias has exactly the same effect as writing the aliased type itself, and writing a reference to a generic type alias has exactly the same effect as writing the resulting instantiation of the aliased type.

The BindingIdentifier of a type alias declaration may not be one of the predefined type names (section 3.8.1).

It is an error for the type specified in a type alias to depend on that type alias. Types have the following dependencies:

  • A type alias directly depends on the type it aliases.
  • A type reference directly depends on the referenced type and each of the type arguments, if any.
  • A union or intersection type directly depends on each of the constituent types.
  • An array type directly depends on its element type.
  • A tuple type directly depends on each of its element types.
  • A type query directly depends on the type of the referenced entity.

Given this definition, the complete set of types upon which a type depends is the transitive closure of the directly depends on relationship. Note that object type literals, function type literals, and constructor type literals do not depend on types referenced within them and are therefore permitted to circularly reference themselves through type aliases.

Some examples of type alias declarations:

  1. type StringOrNumber = string | number;
  2. type Text = string | { text: string };
  3. type NameLookup = Dictionary<string, Person>;
  4. type ObjectStatics = typeof Object;
  5. type Callback<T> = (data: T) => void;
  6. type Pair<T> = [T, T];
  7. type Coordinates = Pair<number>;
  8. type Tree<T> = T | { left: Tree<T>, right: Tree<T> };

Interface types have many similarities to type aliases for object type literals, but since interface types offer more capabilities they are generally preferred to type aliases. For example, the interface type

  1. interface Point {
  2. x: number;
  3. y: number;
  4. }

could be written as the type alias

  1. type Point = {
  2. x: number;
  3. y: number;
  4. };

However, doing so means the following capabilities are lost:

  • An interface can be named in an extends or implements clause, but a type alias for an object type literal cannot.
  • An interface can have multiple merged declarations, but a type alias for an object type literal cannot.