If you’re building a large-scale TypeScript project or just defining a simple data model, you’ll inevitably face this question:
Should I use a
type
or aninterface
?
Letβs break it down in a way that even a sleepy Monday brain can understand β with visuals and code!
π― What Are They?
Both type
and interface
let you define the shape of objects in TypeScript.
// Using interface interface User { name: string; age: number; } // Using type type User = { name: string; age: number; };
π Result? Same thing! But they behave differently when you start scaling your app.
π Key Differences (With Visuals)
1. Extending Types
interface Admin extends User { role: string; } type Admin = User & { role: string };
β Both work. But…
2. Declaration Merging
interface Button { label: string; } interface Button { onClick: () => void; }
β Interface gets merged into:
// Final Button interface Button { label: string; onClick: () => void; }
β type
cannot do this. You’ll get a duplicate identifier error.
π Use Case: Interfaces are great for public APIs and library definitions that evolve over time.
3. Unions and Tuples
type Status = "success" | "error" | "loading"; type Point = [number, number];
β
Only type
supports union, intersection, tuples, primitives, and template literals.
β interface
doesnβt support those.
π§© Visual Summary
Feature | interface β
|
type β
|
---|---|---|
Object Shape | β | β |
Extend Another | β
(extends ) |
β
(& ) |
Declaration Merging | β | β |
Union / Intersection Types | β | β |
Tuples / Primitives | β | β |
π οΈ When to Use Which?
Scenario | Use interface |
Use type |
---|---|---|
Defining a React component’s props | β Yes | β Also works |
Library or shared API models | β Yes | β Avoid |
Unions, intersections, and utility types | β | β Yes |
Working with tuples, strings, or numbers | β | β Yes |
You want to extend multiple object shapes | β Yes | β Yes |
π‘ Real-World Example
// Using interface for React props interface ButtonProps { label: string; onClick: () => void; } const Button = ({ label, onClick }: ButtonProps) => ( <button onClick={onClick}>{label}</button> ); // Using type for API response status type Status = "idle" | "loading" | "error" | "success";
π§ TL;DR
-
β Use
interface
for object shapes and when working in OOP-style systems or public APIs. -
β Use
type
when you need unions, primitives, tuples, or complex compositions.