Question
In TypeScript, what is the difference between using an interface and using a type alias for the following object shape?
interface X {
a: number;
b: string;
}
type X = {
a: number;
b: string;
};
Both appear to describe the same structure. When should each one be used, and how do their behaviors differ in practice?
Short Answer
By the end of this page, you will understand how interface and type alias work in TypeScript, what they have in common, where they differ, and which one is usually better for a given situation. You will also see how these choices affect extension, unions, declaration merging, and real project structure.
Concept
In TypeScript, both interface and type can describe the shape of data.
For simple object shapes, they often look interchangeable:
interface User {
name: string;
age: number;
}
type User = {
name: string;
age: number;
};
In both cases, TypeScript checks whether a value has the required properties with the correct types.
What they have in common
Both can:
- describe object shapes
- be used for function parameters
- be used for return types
- be extended in some way
- work with TypeScript's structural typing system
That means TypeScript mostly cares about the shape of a value, not whether it came from an interface or a type alias.
The main difference
The biggest difference is this:
interfaceis mainly for describing object-like structures and supports declaration mergingtypeis an alias for , including primitives, unions, tuples, intersections, and mapped types
Mental Model
Think of interface as a blueprint for an object.
It says, "Anything calling itself this shape must have these parts."
Think of type as a label you can attach to any kind of type.
It can label:
- an object shape
- a string literal union
- a tuple
- a primitive alias
- a combination of other types
So:
interface= blueprint for object-like structurestype= nickname for any type expression
If you are naming a house layout, interface is the house blueprint.
If you are naming anything at all—house, color, status, coordinates, or a combination—type is the more general label.
Syntax and Examples
Basic object shape with interface
interface User {
name: string;
age: number;
}
const user: User = {
name: "Mia",
age: 25
};
This defines a contract for objects with name and age.
Basic object shape with type
type User = {
name: string;
age: number;
};
const user: User = {
name: "Mia",
age: 25
};
For this case, the result is effectively the same.
type can represent more than objects
Step by Step Execution
Consider this code:
interface X {
a: number;
b: string;
}
const value: X = {
a: 10,
b: "hello"
};
Here is what TypeScript does:
- It reads the
interface Xdeclaration. - It stores the rule that an
Xobject must have:aas anumberbas astring
- It sees
const value: Xand knowsvaluemust match that shape. - It checks the object literal:
a: 10→ valid, because10is a numberb: "hello"→ valid, because"hello"is a string
- The assignment succeeds.
Now the same idea with a type alias:
Real World Use Cases
API response models
Interfaces are often used to describe response objects:
interface ApiUser {
id: number;
email: string;
isAdmin: boolean;
}
This makes it easy to type API data consistently.
Union states in UI code
Type aliases are commonly used for fixed sets of possible values:
type RequestState = "idle" | "loading" | "success" | "error";
This is useful in React, frontend apps, and async workflows.
Function parameter objects
Both are used for configuration objects:
interface FetchOptions {
timeout: number;
retries: number;
}
function fetchData(options: FetchOptions) {
// ...
}
Tuples for coordinates or pairs
Real Codebase Usage
In real codebases, teams usually apply a few simple patterns.
Use interface for domain objects and contracts
Common examples:
UserProductApiResponseFormValues- class contracts with
implements
interface User {
id: number;
name: string;
}
class AdminUser implements User {
id: number;
name: string;
constructor(id: number, name: string) {
this.id = id;
this.name = name;
}
}
Use type for unions and utility composition
Common Mistakes
1. Thinking they are always different in behavior
For simple object shapes, they are often effectively the same.
interface User {
name: string;
}
type UserAlias = {
name: string;
};
Do not assume one changes runtime behavior. Both are erased at compile time.
2. Trying to use interface for a union
Broken code:
// Invalid idea for interface
// interface Status = "open" | "closed";
Use a type alias instead:
type Status = "open" | "closed";
3. Forgetting that interfaces can merge
This can be helpful, but it can also be surprising if the same name appears twice.
interface Config {
port: number;
}
interface Config {
host: ;
}
Comparisons
| Feature | interface | type |
|---|---|---|
| Describes object shapes | Yes | Yes |
| Can alias primitives | No | Yes |
| Can alias unions | No | Yes |
| Can alias tuples | No | Yes |
| Supports declaration merging | Yes | No |
| Can be extended | Yes, with extends | Yes, with & and sometimes extends in interfaces using a type |
Common for class implements |
Cheat Sheet
Quick reference
Use interface when
- defining object-shaped contracts
- describing models like
User,Product,Order - you want declaration merging
- you want a clear contract for classes
interface User {
id: number;
name: string;
}
Use type when
- naming a union
- naming a tuple
- aliasing a primitive
- composing types with
& - creating more advanced type expressions
type ID = string | number;
type Point = [number, number];
type Theme = "light" | "dark";
Similarity
For plain object shapes, both often work:
FAQ
Is interface better than type in TypeScript?
Not universally. interface is often better for object contracts, while type is better for unions, tuples, and advanced type composition.
Are interface and type the same for objects?
For many simple object shapes, yes, they behave very similarly during type checking.
Can a class implement a type alias?
Yes, if the type alias resolves to an object-like shape.
type Person = {
name: string;
};
class User implements Person {
name = "Sam";
}
Can type do something interface cannot?
Yes. type can represent unions, tuples, primitive aliases, and many composed type expressions.
Can interface do something cannot?
Mini Project
Description
Build a small TypeScript model for a blog system to practice when to use interface and when to use type. This project demonstrates a realistic mix: object contracts for entities and type aliases for status values and API result states.
Goal
Create typed blog entities and a typed API result model using both interface and type appropriately.
Requirements
- Create an
interfacefor a blog post withid,title, andcontent. - Create a
typealias for post status using string literals such as"draft"and"published". - Create a combined type for a post plus its status.
- Create a generic API result type for success or failure.
- Write a function that returns a typed API result for a sample post.
Keep learning
Related questions
Angular formGroup Error Explained: Fixing 'Can't bind to formGroup' in Reactive Forms
Learn why Angular shows 'Can't bind to formGroup' and how to fix it by importing ReactiveFormsModule correctly.
Fix "Element implicitly has an 'any' type" in TypeScript Object Indexing
Learn why TypeScript rejects string object indexing and how to fix it with keyof, unions, and typed object keys in React.
Fix "Property has no initializer" in Angular TypeScript Components
Learn why Angular TypeScript shows "Property has no initializer" and how to fix it using defaults, optional properties, or definite assignment.