3秒でわかる
TypeScript で型に名前を付ける 2 つの構文。後から拡張したい型は interface、ユニオン型など型そのものの別名には type を使います。
もう少し詳しく
どういうものか
interface と type はどちらも TypeScript で型に名前を付ける構文です。オブジェクトの形を書く用途ではほぼ同じことができ、どちらで書いてもエディタの補完もエラー検出も変わりません。違いが出るのは、後から拡張するとき、オブジェクト以外の型を表したいとき、そしてエラーメッセージの読みやすさです。
なぜ必要か
同じ形のオブジェクトを何箇所でも扱うとき、毎回インラインで型を書くと修正漏れが起きます。名前を付けておけば定義は 1 箇所で済みます。加えて type はユニオン型やタプル、条件型といった「オブジェクトではない型」にも名前を付けられるため、状態の取りうる値を型で表現する用途では欠かせません。
具体例
interface User {
id: number;
name: string;
}
interface User {
email: string;
}
// 宣言<a href="/glossary/merge-2" class="text-primary font-medium underline underline-offset-2 hover:text-primary-dark">マージ</a>により User は id / name / email を持つ
type Status = "idle" | "loading" | "done";
type Result = { status: Status; user: User } | { status: "error"; message: string };
function render(r: Result) {
if (r.status === "error") return r.message;
return r.user.name;
}つまずきやすいところ
type は同じ名前で 2 回宣言すると重複エラーになる。interface は静かにマージされるので、意図しない拡張に気付きにくいinterface で書こうとして詰まる。interface はオブジェクトの形しか書けないinterface は extends、type は & によるインターセクションinterface の宣言マージしか手が無い似た用語との違い
| 観点 | interface | type |
|---|---|---|
| オブジェクトの形 | 書ける | 書ける |
| ユニオン型 | 書けない | 書ける |
| 同名の再宣言 | マージされる | エラー |
| 拡張 | extends | & で合成 |
覚え方
外から足される可能性があるなら interface、型そのものに別名を付けたいなら type、と分けます。チーム内では片方に寄せる規約を決めてしまうのが最も揉めません。