やあ!TypeScriptの世界へようこそ。
「`interface`と`type`、結局どっちを使えばいいの?」という疑問、これ、TypeScriptを始めた誰もが一度は通る「最初の関門」なんだ。
公式ドキュメントを見ると「`interface`はオブジェクト専用で…`type`は型エイリアスで…」なんて小難しいことが書いてあるけれど、実際の現場で僕たちがどう考えているか、もっと噛み砕いてお話しするね。
—
1. 例え話でイメージしよう:「設計図」と「名前付け」
まずは、この二つを身近なものに例えてみるよ。
- `interface`(インターフェース)は「建築の設計図」
「家を建てるなら、玄関とキッチンと寝室が必要だよね」というように、オブジェクトの形をピシッと決めるものなんだ。拡張されることを前提にした、「ルールブック」のような存在だね。
- `type`(型エイリアス)は「便利な愛称(ニックネーム)」
例えば「`string | number`」という複雑な型に「`ID`」という名前をつけるイメージ。単なる名前付けだけでなく、計算式のように型を組み合わせたり、もっと柔軟なことができる「魔法のタグ」だと思っていいよ。
—
2. 実践!コードで見てみよう
まずは、一番よく使う「オブジェクトの型」を定義してみよう。
// interfaceで定義:まさに「設計図」を書く感じだね
interface User {
name: string;
age: number;
}
// typeで定義:こちらは「この形はこういうものだよ」と定義する感じ
type UserType = {
name: string;
age: number;
};
// どちらを使っても、使う側からすれば結果は同じ!
const me: User = { name: “TypeScript太郎”, age: 25 };
const you: UserType = { name: “TypeScript花子”, age: 22 };
ね? どっちも同じように書けるでしょう? だから最初のうちは「どっちを使っても間違いじゃない」と自分を許してあげてほしいんだ。
—
3. なぜ使い分ける必要があるの?(現場の「推し」ポイント)
じゃあ、なぜ二つもあるのか。そこには現場ならではの「こだわり」があるんだ。
`interface`の必殺技:宣言の結合(Declaration Merging)
これが`interface`最大の強みだよ。同じ名前のインターフェースを別々の場所で書いても、勝手に合体してくれるんだ。
interface Window {
myCustomProperty: string;
}
// あとから同じ名前で定義を足すと…
interface Window {
anotherProperty: number;
}
// Windowには両方のプロパティが自動で追加される!
// ライブラリの型を拡張したいとき、これがないと夜も眠れないほど便利なんだ。
`type`の必殺技:柔軟な組み合わせ
`type`は、型を掛け合わせたり、特定の数値だけを許可したりするのが大得意なんだ。
// 1. 複数の型を合体させる(ユニオン型)
type Status = “success” | “error” | “loading”;
// 2. 既存の型を組み合わせて新しい型を作る(インターセクション型)
type Admin = User & { role: string };
// こういう「計算」はtypeじゃないと綺麗に書けないことが多いよ。
—
4. 結局、どう使い分けるのが正解?
伝説のアーキテクトとしての僕の結論はこうだ。
1. 基本は `interface` を使おう
オブジェクトの形を定義するなら、まずは`interface`。なぜならエラーメッセージが親切だし、何より「これは設計図だよ」という意図がチームのみんなに伝わりやすいからね。
2. `type` は「型を加工したいとき」に使う
「AまたはB(`|`)」「AかつB(`&`)」のような、少し凝ったことをしたいときは迷わず`type`へ。
—
最後に:あまり難しく考えないで
TypeScriptを始めたばかりの頃は、「どっちが正しい設計か」と悩みすぎて手が止まってしまうことが一番の損失なんだ。
「最初は interface で書いてみて、どうしても型を組み合わせたくなったら type に書き換える」
これくらいの軽い気持ちでいいんだよ。コードは生き物だから、後からいくらでもリファクタリング(修正)できる。大切なのは、君が書いたコードが「誰にとっても読みやすいか」という一点だけ。
つまずいたら、いつでもまたここに戻っておいで。応援しているよ!

コメント