Interface vs Type Alias in TypeScript: What's the Difference?
Compare TypeScript interfaces and type aliases: declaration merging, unions and tuples, extends vs intersection, and when to choose each in interviews.
Expected Interview Answer
Interfaces and type aliases both describe the shape of an object, but interfaces support declaration merging and are best for extendable object contracts, while type aliases can name any type at all, including unions, tuples, and mapped types, but cannot be reopened once declared.
An interface declared twice with the same name automatically merges its members into one, which library authors rely on to let consumers augment third-party types. A type alias, by contrast, throws a duplicate-identifier error if declared twice, but it can represent things an interface never can, such as 'string | number', a tuple like '[string, number]', or a mapped type built from another type's keys. Interfaces extend other interfaces with the 'extends' keyword and can be implemented by classes; type aliases combine other types with intersections using '&'. In modern TypeScript both compile to nearly identical structural checks for plain object shapes, so the choice mostly comes down to whether you need merging and class implementation (interface) or union, tuple, and computed types (type alias).
- Interfaces merge declarations, useful for extending library types
- Type aliases can express unions, tuples, and mapped types
- Both check structurally compatible for plain object shapes
- Interfaces are implementable by classes directly
- Type aliases compose via intersections for flexible modeling
AI Mentor Explanation
An interface is like a club's official playing conditions document that any ground can add local clauses to over time, and those clauses merge into one master rulebook everyone follows. A type alias is more like a specific match format such as T20 versus a Test — you name it once, it can combine features from other formats, but you cannot quietly reopen and redefine what T20 means after it is set.
Step-by-Step Explanation
Step 1
Object shape declaration
Both 'interface Foo { ... }' and 'type Foo = { ... }' describe an object's shape and are checked structurally for compatibility.
Step 2
Declaration merging
Declaring the same interface name twice merges their members automatically; declaring the same type alias name twice is a compile error.
Step 3
Extending vs intersecting
Interfaces extend with 'extends'; type aliases combine other types with the '&' intersection operator to similar effect for objects.
Step 4
Beyond object shapes
Type aliases can name unions, tuples, primitives, and mapped or conditional types — forms an interface cannot express.
Step 5
Class implementation
Classes implement interfaces directly with 'implements'; they can also implement an object-shaped type alias, but unions or tuples cannot be implemented.
What Interviewer Expects
- States that interfaces merge and type aliases do not
- Knows type aliases can express unions, tuples, and mapped types
- Explains extends (interface) versus & intersection (type alias)
- Understands both are structurally compatible for plain objects
- Gives a practical rule of thumb for when to choose each
Common Mistakes
- Claiming type aliases and interfaces are functionally identical in every case
- Forgetting that interfaces support declaration merging and type aliases do not
- Trying to declare a union or tuple using interface syntax
- Assuming intersections and extends always behave identically on conflicting members
Best Answer (HR Friendly)
“Both interfaces and type aliases are ways to describe the shape of data in TypeScript, and for simple cases they work almost the same. The key practical difference is that interfaces can be extended or added to later by other parts of the code, which is handy for shared libraries, while type aliases are better when you need to describe more flexible combinations like 'this or that' options.”
Code Example
// Interfaces merge automatically
interface Window {
title: string;
}
interface Window {
isOpen: boolean;
}
// Window now has both title and isOpen
// Type aliases cannot be redeclared
type Config = { retries: number };
// type Config = { timeout: number }; // Error: Duplicate identifier 'Config'
// Type aliases can express unions and tuples an interface cannot
type Id = string | number;
type Point = [x: number, y: number];
// Interface extends vs type intersection
interface Base { id: Id }
interface Extended extends Base { name: string }
type BaseT = { id: Id };
type ExtendedT = BaseT & { name: string };Follow-up Questions
- What is declaration merging and which construct supports it?
- Can a type alias represent a union type? Can an interface?
- How does 'extends' differ from '&' when members conflict?
- Can a class implement a type alias the same way it implements an interface?
- When would you deliberately choose a type alias over an interface?
MCQ Practice
1. Which construct supports automatic declaration merging?
Interfaces merge automatically when declared multiple times with the same name; type aliases throw a duplicate-identifier error instead.
2. Which of these can a type alias express that an interface cannot?
Type aliases can name union types, tuples, and other non-object forms, which interfaces cannot directly represent.
3. How do type aliases combine with other types to add members?
Type aliases use the & intersection operator to combine multiple types, which is analogous to an interface's extends clause.
Flash Cards
Which supports declaration merging: interface or type alias? — Interface. Declaring the same interface name twice merges the members; a type alias errors on redeclaration.
Name something a type alias can express that an interface cannot. — Union types, tuples, primitives, and mapped or conditional types.
How does an interface add members from another type? — Using the extends keyword.
How does a type alias add members from another type? — Using the & intersection operator.