Introduction
TypeScript helps developers write safer and more maintainable JavaScript code by adding static typing. Two of the most commonly used features in TypeScript are Interfaces and Type Aliases.
At first glance, they seem very similar because both can define the shape of an object. However, they have important differences that affect how you design and maintain applications.
In this article, you'll learn the differences between Interfaces and Type Aliases, when to use each one, and best practices for real-world projects.
What Is a TypeScript Interface?
An Interface defines the structure of an object.
Example:
interface User {
id: number;
name: string;
email: string;
}
Usage:
const user: User = {
id: 1,
name: "John",
email: "[email protected]"
};
The object must follow the structure defined by the interface.
What Is a Type Alias?
A Type Alias creates a custom type using the type keyword.
Example:
type User = {
id: number;
name: string;
email: string;
};
Usage:
const user: User = {
id: 1,
name: "John",
email: "[email protected]"
};
In this simple example, the result looks almost identical to an interface.
Key Difference #1: Declaration Merging
Interfaces support declaration merging.
Example:
interface User {
id: number;
}
interface User {
name: string;
}
TypeScript automatically combines them:
interface User {
id: number;
name: string;
}
Type Aliases do not support this.
type User = {
id: number;
};
type User = {
name: string;
};
This causes an error.
Key Difference #2: Union Types
Type Aliases work well with unions.
Example:
type Status =
| "Pending"
| "Approved"
| "Rejected";
Usage:
let status: Status = "Approved";
Interfaces cannot directly create union types.
This is one of the biggest advantages of Type Aliases.
Key Difference #3: Primitive Types
Type Aliases can represent primitive values.
Example:
type UserId = number;
type UserName = string;
Interfaces cannot do this.
interface UserId = number;
This is invalid.
Key Difference #4: Extending Types
Interfaces can extend other interfaces.
interface Person {
name: string;
}
interface Employee extends Person {
department: string;
}
Type Aliases use intersections.
type Person = {
name: string;
};
type Employee = Person & {
department: string;
};
Both approaches achieve similar results.
Real-World Example
Imagine an e-commerce application.
Product model:
interface Product {
id: number;
name: string;
price: number;
}
Order status:
type OrderStatus =
| "Pending"
| "Shipped"
| "Delivered";
In this scenario:
Interface defines object structure.
Type Alias defines possible values.
Many projects use both together.

Join the conversation! Your thoughts help the community grow.