😺
TypeScriptのtypeとinterfaceの違いを解説
基本的な違い
interface(インターフェース)
- オブジェクトの形状を定義するのに特化
- 同じ名前で再宣言すると自動的にマージされる
- extendsで継承可能
type(型エイリアス)
- あらゆる型を定義できる(オブジェクト、ユニオン型、プリミティブ型など)
- 再宣言できない
- &(交差型)で拡張可能
具体例で比較
1. 基本的な使い方
// ✅ どちらも同じように使える
interface UserInterface {
id: number
name: string
}
type UserType = {
id: number
name: string
}
2. 拡張・継承
// interface - extendsで継承
interface Animal {
name: string
}
interface Dog extends Animal {
breed: string
}
// type - 交差型(&)で拡張
type Animal = {
name: string
}
type Dog = Animal & {
breed: string
}
3. typeだけができること
// ✅ ユニオン型
type Status = 'pending' | 'completed' | 'failed'
// ✅ プリミティブ型のエイリアス
type UserId = string
// ✅ タプル型
type Coordinate = [number, number]
// ❌ interfaceではできない
interface Status = 'pending' | 'completed' // エラー!
4. interfaceだけができること
// ✅ 同名で宣言するとマージされる
interface User {
name: string
}
interface User {
age: number
}
// 結果: User は { name: string; age: number } になる
// ❌ typeは再宣言できない
type User = { name: string }
type User = { age: number } // エラー!
使い分けの指針
interfaceを使う場面
// ✅ Reactコンポーネントのprops
interface ButtonProps {
label: string
onClick: () => void
}
// ✅ クラスの実装
interface Flyable {
fly(): void
}
class Bird implements Flyable {
fly() { /* ... */ }
}
typeを使う場面
// ✅ ユニオン型
type Theme = 'light' | 'dark'
// ✅ 関数の型
type ClickHandler = (event: MouseEvent) => void
// ✅ 複雑な型の組み合わせ
type ApiResponse<T> = {
data: T
status: 'success' | 'error'
}
自分のコードの場合
// ✅ props定義なのでinterface(推奨)
interface BulkListProps {
ownerId: number
}
// 🤔 オブジェクトの形状だけなので、interfaceでも良い
interface Bulk {
id: number
createdAt: string
totalUrls: number
}
まとめ
- オブジェクトの形状だけなら → interface
- ユニオン型や複雑な型なら → type
- Reactのpropsなら → interface(慣習的に)
- 迷ったら → チームの規約に従う、なければtypeで統一
Discussion