1. Introduction
TypeScript offers two ways to name a shape: interface and type (type alias). Both can describe object shapes and are largely interchangeable for that purpose, but they diverge in capability and behavior. Understanding the differences helps you choose the right tool and avoid surprises around merging, extension, and what kinds of types can be represented.
Cricket analogy: Choosing between interface and type is like choosing between two scorecard templates that both record an innings fine, but only one lets you staple extra pages onto the same sheet later.
2. Syntax
// interface
interface Animal {
name: string;
sound(): string;
}
// type alias — equivalent object shape
type AnimalType = {
name: string;
sound(): string;
};
// type alias can also do things interfaces cannot:
type Id = string | number; // union
type Coordinates = [number, number]; // tuple
type Callback = (data: string) => void; // function type shorthand3. Explanation
For plain object shapes, interface and type behave almost identically — both support optional properties, readonly modifiers, methods, and index signatures. The key differences appear at the edges: interfaces support declaration merging (re-opening the same interface name adds more members to it), while type aliases are single-shot — declaring type X twice with the same name is a compile error.
Cricket analogy: Both an interface-style and type-style team sheet can list an optional twelfth-man slot and a readonly captain field fine, but only the interface version lets you reopen the same sheet in a later innings to add more required fields.
Type aliases, on the other hand, can name things interfaces fundamentally cannot: union types (type Status = 'ok' | 'error'), primitive aliases (type Id = string), tuples, and mapped/conditional types. Interfaces can only describe object-like shapes (including callable and constructable signatures), never a union of primitives.
Cricket analogy: A type alias can name type MatchResult = 'win' | 'loss' | 'tie' the way a scoreboard lists every possible outcome of a match, something a team-sheet-style interface simply has no way to express.
Gotcha: extending shapes looks different depending on which you use. Interfaces extend other interfaces with the extends keyword and support extending multiple interfaces at once. Type aliases combine shapes using intersection (&) instead — there is no extends clause for a plain object type alias. Mixing the two idioms (e.g. trying type X extends Y) is a syntax error.
4. Example
interface HasId {
id: number;
}
type HasIdAlias = {
id: number;
};
// Interfaces merge automatically.
interface HasId {
createdAt: Date;
}
// type Status cannot be expressed as an interface — it's a union of
// literal strings, not an object shape.
type Status = "pending" | "active" | "closed";
function describe(status: Status): string {
return `Order is ${status}`;
}
const record: HasId = { id: 1, createdAt: new Date("2024-01-01") };
console.log(Object.keys(record));
console.log(describe("active"));5. Output
[ 'id', 'createdAt' ]
Order is active6. Key Takeaways
- Both interface and type can describe object shapes; for that purpose they are largely interchangeable.
- Only interfaces support declaration merging — redeclaring the same interface name combines members.
- Only type aliases can represent unions, primitives, tuples, and other non-object-shaped types.
- Interfaces extend with 'extends' (and can extend multiple interfaces); object type aliases combine with intersection '&'.
- A common convention: use 'interface' for public object/class contracts meant to be extended, 'type' for unions, tuples, and complex derived types.
Practice what you learned
1. Which of the following can ONLY be expressed with `type`, not `interface`?
2. What happens if you write `type Config = { debug: boolean }` twice in the same scope with the same name?
3. How do you combine two object shapes using type aliases, since 'extends' is not available for them?
4. For a simple object shape like `{ id: number; name: string }`, which statement is most accurate?
5. Which capability is unique to `interface` and not available to `type`?
Was this page helpful?
You May Also Like
Interfaces in TypeScript
Learn how TypeScript interfaces describe the shape of objects using structural typing, and why they are the primary tool for contract-based design.
Type Aliases in TypeScript
Use `type` to give a name to any type -- primitives, unions, tuples, function signatures, and more.
Union and Intersection Types in TypeScript
Combine types with `|` (union) and `&` (intersection) to model values that can be one of several shapes or must satisfy all of them.
Extending Interfaces in TypeScript
Learn how the `extends` keyword lets one interface inherit and build upon the members of one or more other interfaces.
Discriminated Unions in TypeScript
Use a shared literal 'tag' property across union members so TypeScript can narrow exactly which member you're handling in a switch or if.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics