TypeScriptのinterfaceとtypeの違いって?3つの違いと使い分け方
TypeScriptを書き始めると、「どちらで型を定義すればいいんだろう」と迷う場面が必ず来ます。
この記事では、interfaceとtypeの具体的な違いを整理したうえで、「どちらをいつ使えばいいか」の判断基準をわかりやすく説明します。
この記事は次のような方におすすめです。
- TypeScriptでinterfaceとtypeを見たことはあるが、違いがわからない方
- コードを書くとき、どちらで定義するか毎回迷ってしまう方
- 使い分けの判断基準をシンプルに把握したい方
この記事を読むと、interfaceとtypeが「どこで違うのか」「どちらを選べばいいか」がはっきりわかるようになります。
それでは、順を追って詳しく見ていきましょう!
- 未経験で後悔したくない
【実体験】未経験からITエンジニアに転職して後悔した話|4社経験してわかった「最初の選択ミス」 - 年収が低くて不安
4年間ずっと年収260万だったエンジニアが、転職で510万になるまでの全記録
interfaceとtypeの違いを一言でいうと
まず大前提として、interfaceとtypeはできることが大きく重なっています。 どちらを使っても書けるケースがほとんどで、「全然別物」ではなく「ほぼ同じことができるが、一部だけ差がある」と思っておくとわかりやすいです。
その差がどこにあるかを、これから見ていきます。
interfaceはオブジェクトの「形」を定義するもの
interfaceは、オブジェクトがどんなプロパティを持つかを定義するための構文です。
interface User {
name: string;
age: number;
}
User型を持つ変数にはname(string型)とage(number型)が必要、という「形」を定義しています。
typeはもっと幅広い型を定義できるもの
typeはオブジェクトだけでなく、さまざまな形の型に名前を付けられるのが特徴です。
type User = {
name: string;
age: number;
};
オブジェクトを定義するだけなら、interfaceとほぼ同じ書き方ができます。さらにtypeは、ユニオン型やプリミティブ型のエイリアスなど、interfaceではできない定義にも対応しています。
実際に違いが出る3つのポイント
「ほぼ同じ」とはいえ、いくつか明確に差が出る場面があります。ここでは特に知っておきたい3つのポイントに絞って整理します。
宣言のマージ — interfaceは同名で追記できる、typeはできない
interfaceは同じ名前で複数回宣言すると、自動的にマージ(合体)されます。 typeは同名で再定義しようとするとエラーになります。
// interfaceは同名で追記できる
interface User {
name: string;
}
interface User {
age: number;
}
// → { name: string; age: number; } として扱われる
// typeは同名で定義しようとすると両方エラー
type User = { name: string }; // ❌ エラー(重複した識別子)
type User = { age: number }; // ❌ エラー(重複した識別子)
自分でコードを書く場面でこれを意図的に使う機会はほぼありませんが、「interfaceは追記できる・typeはできない」という差として覚えておくと役立ちます。
この仕組みは「Declaration Merging(宣言のマージ)」と呼ばれます。外部ライブラリの型定義ファイル(.d.ts)で既存のinterfaceにプロパティを追加したいときなどに使われています。自分が書くコードで多用するものではありませんが、ライブラリのソースコードを読むときに「なぜ同名のinterfaceが複数あるのか」がわかるようになります。
拡張の書き方 — extendsと&(交差型)
既存の型をもとに新しい型を作りたいとき、interfaceはextendsを使い、typeは&(交差型)を使います。
// interfaceの拡張
interface Animal {
name: string;
}
interface Dog extends Animal {
breed: string;
}
// Dog は { name: string; breed: string; }
// typeの拡張
type Animal = { name: string };
type Dog = Animal & { breed: string };
// Dog は { name: string; breed: string; }
「Animal の型を引き継いだ Dog を定義する」という型の形は同じです。
ただし、TypeScript公式のパフォーマンスガイドではextendsの使用を推奨しています。 interface extends はコンパイラが型をキャッシュできるのに対し、type &(交差型)は毎回再計算されるためです。また、interface extends はプロパティが重複しているときにエラーで教えてくれますが、type & は黙って never 型に推論されることがあります。
typeだけができること — ユニオン型・プリミティブのエイリアス
interfaceではオブジェクトの形しか定義できませんが、typeはユニオン型やプリミティブ型のエイリアスも定義できます。
// ユニオン型(typeでしか書けない)
type Status = "active" | "inactive" | "pending";
// プリミティブ型に名前を付ける(typeでしか書けない)
type ID = string;
type Count = number;
"active" | "inactive" | "pending" のように「このどれかの値」という型は、interfaceでは表現できません。このようなケースではtypeを使う必要があります。
結局どちらを使えばいいのか
違いを把握したうえで、一番気になる「で、どっちを使えばいいの?」に答えます。
オブジェクトの型定義ならどちらでも書ける
まず重要なのは、オブジェクトの型定義に限っては、interfaceでもtypeでも同じように書けます。 どちらを選んでも間違いではありません。
// どちらも同じ意味で使える
interface User { name: string; age: number; }
type User = { name: string; age: number; };
typeを選ぶべき場面
次のケースではtypeを使うのが自然です。
- ユニオン型を定義したいとき(
"active" | "inactive"など) - プリミティブ型に別名を付けたいとき(
type ID = stringなど) - 複数の型を
&で合成したいとき
interfaceを選ぶべき場面
次のケースではinterfaceの方がしっくりきます。
- クラスに
implementsで型を適用したいとき(interfaceはclassとの相性がよい) - 宣言のマージで外部ライブラリの型を拡張したいとき
迷ったときの判断軸
「どちらでもいい場合はどうすればいい?」という疑問には、公式ドキュメントやコミュニティの見解が参考になります。ただ、立場によって推奨が異なるので整理しておきます。
TypeScript公式(現行ドキュメント)はinterfaceを目安として推奨
TypeScript公式ハンドブックの現行ドキュメント(Everyday Types)には、次のように書かれています。
“For the most part, you can choose based on personal preference, and TypeScript will tell you if it needs something to be the other kind of declaration. If you would like a heuristic, use
interfaceuntil you need to use features fromtype.”
引用:TypeScript Handbook – Everyday Types
「個人の好みで選んでかまわない、ただし目安としてはinterfaceを使い、typeの機能が必要になったらtypeに切り替えればよい」というスタンスです。絶対的な強制ではなく、迷ったときの目安として示されています。
Googleのスタイルガイドはinterfaceを推奨(ただしTypeScript公式ではない)
Googleが公開しているTypeScriptスタイルガイドには、次の記述があります。
“when declaring types for objects, use interfaces instead of a type alias for the object literal expression.”
引用:Google TypeScript Style Guide
オブジェクトの型定義にはinterfaceを使うよう明記されています。ただしこれはGoogleが社内ルールとして定めたものであり、TypeScript公式のスタイルガイドではありません。
コミュニティ(専門家)はtypeを推奨する意見も多い
一方、TypeScriptのエキスパートとして知られるMatt Pocock(Total TypeScript)は逆の立場を取っています。
“The TS team recommends you default to using
interfaceand only usetypewhen you need to. I’d like to recommend the opposite.”
“I’d recommend you usetypeby default. It’s a little more flexible and a little less surprising.”
引用:Total TypeScript – Type vs Interface: Which Should You Use?
interfaceには宣言のマージやインデックスシグネチャとの互換性など、意図しない挙動を招く性質があるため、「デフォルトはtypeにして、interfaceが必要な場面だけinterfaceを使えばよい」というわけです。
結論
公式の目安はinterfaceですが、専門家コミュニティではtypeを推すケースも多く、絶対的な正解はありません。迷ったときは次の基準で選んでください。
- typeでしかできない定義が必要なとき type
- それ以外のオブジェクト定義 プロジェクトのルールに合わせる。ルールがなければinterfaceをデフォルトにしておくのが公式の目安
プロジェクト内でどちらかに統一されていること自体が大切です。
【付録】さらに学びを深めるためのリソース
さらにTypescriptの学習を進めたい方のために、いくつかのリソースを紹介します。
これらのリソースを活用することで、TypeScriptの型システムについてより深い知識を得ることができるでしょう。
おすすめの書籍
ゼロからわかる TypeScript入門
技術評論社から出版されている「ゼロからわかる TypeScript入門」は、プログラミング初心者や本職プログラマーではない方を主な対象にした入門書です。
変数・条件分岐・ループといった基本から、クラスやインターフェース、モジュールまで段階的に学べる構成になっています。最終章ではWeb APIとJSONを使った非同期Webアプリの作成も体験できるので、「実際に動くものを作る」ところまで到達できます。
プロを目指す人のためのTypeScript入門
技術評論社の「プロを目指す人のためのTypeScript入門 安全なコードの書き方から高度な型の使い方まで」、通称 ブルーベリー本 です。
JavaScriptの仕様とTypeScript独自の機能を両方押さえつつ、リテラル型・ユニオン型・keyof型・ジェネリクスなど、高度な型表現まで踏み込んで解説しています。TypeScriptの型システムの表現力を本格的に学べる一冊です。
オンラインで参照できる公式ドキュメント
TypeScript公式ハンドブック
https://www.typescriptlang.org/docs/
TypeScriptの公式ドキュメントです。
intersection型を含む、すべての型システムの機能について詳細な説明があります。
TypeScript Deep Dive
https://basarat.gitbook.io/typescript/
TypeScriptの深い部分まで掘り下げて解説しているオンラインブックです。
無料で読むことができ、intersection型についても詳しく説明されています。
TypeScriptの学習は終わりがありません。
新しい機能が常に追加され、より良い書き方が発見されています。
継続的に学習を続けることで、より良いTypeScriptプログラマーになれるはずです。
まとめ — interfaceとtypeの違いと使い分けの基準
この記事で整理した内容をまとめます。
- interfaceとtypeは、オブジェクトの型定義においてはほぼ同じことができる
- 主な違いは「宣言のマージ(interfaceのみ)」「拡張の書き方(extendsと&)」「typeだけができる型(ユニオン型・プリミティブエイリアス)」の3点
- typeを選ぶ明確な場面は、ユニオン型など interfaceでは書けないときに限られる
- 公式ドキュメントはinterfaceを目安として推奨しているが、コミュニティではtypeを推奨する声も多い
「正解を選ばなければ」と気負わず、まずはプロジェクトや既存コードのルールに合わせることから始めてみてください。
※本記事の本文案はAIを活用して作成していますが、記載している内容およびコードは筆者が実際に調査、検証・実行し、内容の正確性を確認した上で公開しています。






