“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
interface
when describing objects and props.Use
type
for 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)