Skip to content
Theory · Object types · lesson 2 of 7

Type aliases

A real form has a title printed at the top: "Employee form". Nobody reads all its fields out loud. People say "fill in the employee form", and everyone knows which blank is meant.

While an object's shape has no name, { name: string; age: number } has to be repeated wherever a user is needed: three functions mean three identical copies. And if the form gains an email field, all three must be edited, and one of them can be missed.

The keyword type gives a shape a name:

TypeScript
type User = {
    name: string;
    age: number;
};

function describe(user: User): string {
    return `${user.name}, ${user.age}`;
}

function olderOf(a: User, b: User): User {
    return a.age >= b.age ? a : b;
}

const ann: User = { name: "Ann", age: 30 };
console.log(describe(olderOf(ann, { name: "Bob", age: 25 }))); // Ann, 30

Let's go through the example:

  1. Lines 1–4 declare the type alias User, a name for the shape { name: string; age: number }. You have already seen this notation on a list of literals, type Size = "S" | "M" | "L"; here the name goes to an object shape.
  2. describe takes a User and returns a string.
  3. olderOf takes two users and returns the older one, also a User.
  4. The constant ann is declared with the type User, and the compiler checks its literal the same way it would check the full shape.
  5. The program prints Ann, 30: of the two users, ann is older.

How a type declaration is built

The declaration type User = { … }; has four parts:

  • the keyword type;
  • a name, capitalized by convention: User, Order, Point;
  • the = sign and the type itself;
  • a semicolon at the end.

An alias can go anywhere a type is written: on a variable, on a parameter, on a function's result, inside another type. Like everything about types, it exists only for the compiler and never reaches the JavaScript file.

An alias for a union

type names any type: an object shape, like User, a list of literals, like Size, and a union of ordinary types:

TypeScript
type Id = string | number;

function showId(id: Id) {
    console.log(`id: ${id}`);
}

showId(7); // id: 7
showId("a-15"); // id: a-15

The name Id is shorter than string | number and says what the value is for. If ids later become strings only, one line with type is all you change.

Errors use the name

When a type has a name, the compiler's messages use it instead of the whole shape:

TypeScript
type User = { name: string; age: number };

const bob: User = { name: "Bob" }; // ✗
TEXT
error TS2741: Property 'age' is missing in type '{ name: string; }' but required in type 'User'.

Without the alias, the end of this message would hold the whole shape { name: string; age: number; }; here it is a short User. The editor shows the name too: the hover over bob says User. A union works the same way: pass true to showId, and the error ends with parameter of type 'Id'.

A name, not a new type

An alias creates no new type but gives an existing type a second name. Here the form analogy stops working: in an HR office, two forms with different titles are two different blanks, even when their fields match. To TypeScript, type Age = number means only "Age is another name for number":

  • any number can go into an Age;
  • a value of type Age fits wherever a number is expected;
  • for the constant const a: Age = 30 the editor shows the type number, not Age.

Common mistake

Expecting the compiler to tell two aliases of one type apart:

TypeScript
type UserId = number;
type OrderId = number;

function findUser(id: UserId) {
    console.log(`user #${id}`);
}

const orderId: OrderId = 42;
findUser(orderId); // ✗

The compiler stays silent, and the program prints user #42: the function looks up a user by an order's number. UserId and OrderId are both number, and the compiler sees no difference between names of one type. An alias helps the reader of the code but does not guard against mix-ups, so check such places yourself, for example by giving parameters and variables telling names.

Key points

  • type Name = type; names any type: an object shape, a union, a set of literals.
  • An alias is declared once and written wherever the type is needed, and the shape changes in one place.
  • Errors and editor hovers show the alias name of an object or a union, not the whole shape.
  • An alias is a second name, not a new type: to the compiler UserId and OrderId are the same.