Taming TypeScript

The TypeScript Tutorial for The Hater

`interface` vs. `type`: A Simple, Pragmatic Guide

Two Ways to Describe an Object?

So far, we've used type aliases to describe the shape of our objects, and it's worked great. But if you look at other TypeScript code, you'll quickly see another keyword used for the same purpose: interface.

// Using a type alias
type UserType = {
  id: number;
  name: string;
};

// Using an interface
interface UserInterface {
  id: number;
  name: string;
}

(Notice that type aliases use an = sign, but interfaces do not. It's just a small syntactic difference.)

This is one of the most common points of confusion for newcomers. Why are there two ways to do the same thing? Which one should you use?

The good news is that for describing basic object shapes, they are almost identical. The bad news is that they have subtle differences that can be confusing. Let's clear it up with a simple, pragmatic guide.

The Similarities

For 90% of your daily work, type and interface are interchangeable for describing objects. You can define properties, make them optional, and use them to type variables and functions in the exact same way.

Both can also be extended, though the syntax differs slightly.

Interactive Editor
Loading...

The Key Differences (and Our Recommendation)

There are two key differences that inform which one you should choose.

1. type can do more than just objects. A type alias is more flexible. It can be used to give a name to any type, including primitives, unions, or complex combinations.

type ID = string | number; // Can't do this with an interface
type Status = 'pending' | 'success'; // Can't do this with an interface

An interface can only be used to declare the shape of an object.

2. interface can be "merged". You can declare the same interface multiple times, and TypeScript will merge their definitions.

interface Window {
  title: string;
}
// ... somewhere else in the codebase ...
interface Window {
  ts: any; // This gets added to the Window interface
}

This is called "declaration merging" and it's primarily useful for augmenting existing types from external libraries (like adding properties to the global Window object). A type alias, once defined, cannot be changed or merged.

Recommendation: When to Use type vs. interface

So, which one should you use? Here's our simple recommendation:

Always use type for your application code. Use interface only if you are a library author and need to provide a type that you expect consumers of your library to extend via declaration merging.

Using type is more consistent, as it can be used for any kind of type, not just objects. This consistency simplifies your codebase. The one major feature of interface (declaration merging) is rarely needed in day-to-day application development and can sometimes lead to unexpected behavior if used incorrectly.

Exercise: Convert a type to an interface

To prove to yourself that they are very similar for basic objects, convert the User type alias below into an interface.

Interactive Editor
Loading...
Click to see the solution
interface User {
  id: number;
  name: string;
  isVerified?: boolean;
}

const user: User = {
  id: 1,
  name: "Luigi"
};