Back to roadmaps typescript Course

Interface vs Type Aliases

When defining object structures in TypeScript, you have two primary options: Interface and Type Aliases. While they look similar and can often be used interchangeably, they have subtle differences that affect code design.


1. Syntax Comparison

Here is how you declare an object structure using both methods:

Using Interface

interface UserAccount {
  id: string;
  email: string;
}

Using Type Alias

type UserProfile = {
  id: string;
  email: string;
};

Both approaches can be used to type variables and function parameters.


2. Key Differences

Let us explore the core differences in how they behave.

A. Extending Types

Interfaces extend other interfaces using the extends keyword. Type aliases extend other types using intersection types (&).

Extending an Interface

interface Client {
  name: string;
}

interface VIPClient extends Client {
  discount: number;
}

Extending a Type Alias

type Employee = {
  name: string;
};

type Manager = Employee & {
  department: string;
};

B. Declaration Merging (Unique to Interface)

If you declare multiple interfaces with the exact same name in the same scope, TypeScript automatically merges their property definitions together.

interface Setting {
  theme: string;
}

interface Setting {
  fontSize: number;
}

// The merged interface contains both properties:
const myConfig: Setting = {
  theme: "dark",
  fontSize: 16
};

Type aliases cannot be declared multiple times with the same name. Attempting to do so will result in a compiler error.


C. Capability Mapping

Type aliases are more expressive because they can represent union types, primitive types, tuples, and mapped types. Interfaces are strictly limited to describing object shapes.

// Type alias representing a Union (Not possible with Interface)
type StatusID = number | string;

// Type alias representing a Tuple
type Coordinates = [number, number];

3. Best Practices: Which One to Choose?

In modern TypeScript, follow these general guidelines:

  • Use Interface for Objects: Use interfaces to describe object structures, classes, or API contracts. This allows other developers to extend or merge them if they import your library.
  • Use Type Aliases for Utilities: Use type aliases when you need to represent unions, primitives, tuples, intersections, or complex type logic (like mapped types).

4. Summary

  • Interfaces can be merged through declaration merging and extended using extends.
  • Type aliases are more flexible, supporting unions, tuples, and primitive mapping.
  • Use interfaces by default for public API shapes to allow extensibility.
  • Use type aliases when leveraging the advanced power of the type system.
Published on Last updated: