“Wait… why do we have two ways to do the same thing?”
If you’ve been writing React with TypeScript, you’ve probably seen both interface and type. And maybe you’ve wondered:
“Which one should I use?”
In this article, I’ll show you the difference using easy language and real React examples.
🎨 What's the Goal?
Both interface and type help you describe the shape of data.
Imagine you're drawing a character in a video game. You want to say:
// This character has a name and health points.
{
name: "Knight",
hp: 100
}
We can tell TypeScript what that looks like using:
Option A: interface
interface Character {
name: string;
hp: number;
}
Option B: type
type Character = {
name: string;
hp: number;
}
💡 Both do the same thing here.
✅ So… What’s the Difference?
Let’s go deeper and see what makes them different.
1. Extending = Making it Bigger
Let’s say you want a Wizard character that also has mana.
With interface:
interface Character {
name: string;
hp: number;
}
interface Wizard extends Character {
mana: number;
}
With type:
type Character = {
name: string;
hp: number;
}
type Wizard = Character & {
mana: number;
}
🧠 Tip: interface uses extends, and type uses &.
2. Mixing Multiple Declarations
With interface, you can do this:
interface Player {
name: string;
}
interface Player {
score: number;
}
// Player = { name: string; score: number }
With type, this would give you an error:
type Player = {
name: string;
}
type Player = {
score: number;
} // ❌ Error: Duplicate identifier
🧠 Use interface if you want to allow merging in the future (useful for libraries).
🚀 Real React Examples
Let’s now see how to use interface and type in real React components.
🔹 Props with interface (Recommended)
interface ButtonProps {
label: string;
onClick: () => void;
disabled?: boolean;
}
const Button: React.FC<ButtonProps> = ({ label, onClick, disabled }) => {
return <button disabled={disabled} onClick={onClick}>{label}</button>;
};
✅ Clear and extensible. Most teams prefer interface for component props.
🔹 Props with type (Also works)
type ButtonProps = {
label: string;
onClick: () => void;
disabled?: boolean;
};
const Button = ({ label, onClick, disabled }: ButtonProps) => {
return <button disabled={disabled} onClick={onClick}>{label}</button>;
};
✅ Also good, especially if you want to combine with other types later.
🤹♀️ Composing Types
type WithId = {
id: string;
}
type Post = WithId & {
title: string;
body: string;
}
Great when you want to “mix” types. This is a superpower of type.
📦 Typing Models (e.g., API Data)
interface User {
id: string;
name: string;
email: string;
createdAt: string;
}
Useful when you’re working with APIs - interface makes it easy to extend later.
🧾 When to Use Which?
| Use Case | Use interface ✅ |
Use type ✅ |
|---|---|---|
| Component props | ✅ Preferred | ✅ Works fine |
| React models (API objects) | ✅ Recommended | ✅ Optional |
| Composing multiple types | 🚫 Limited | ✅ Super flexible |
| Union types (A or B) | ❌ Not supported | ✅ Only with type
|
| Tuples, functions, primitives | ❌ Not supported | ✅ Only with type
|
| You’re building a library | ✅ Merge-friendly | ❌ No merging |
🎯 The Final Tip (Like a Pro)
Use
interfacewhen describing objects and props.Use
typefor everything else (unions, functions, compositions).
And most importantly:
Be consistent in your codebase. Mixing is okay, but don’t confuse your future self. 😅
💬 Want to Practice?
Try converting a type to an interface and vice versa in one of your components.
Or type out a model for your favorite Pokémon or Star Wars character!
🙌 Thanks for Reading!
If you enjoyed this, drop a ❤️ or comment below!
Let’s keep making TypeScript less scary, one type at a time.
#typescript #react #beginners #webdev #devto
Top comments (0)