転職を繰り返したサラリーマンの多趣味ブログ

30才未経験でSEに転職した人の多趣味ブログ

TypeScriptのtypeとinterfaceの違いを整理してみた【ユニオン型も解説】

こんにちは。今日は TypeScript の typeinterface の違い、そしてよく一緒に出てくる ユニオン型 についてまとめます。
自分の勉強メモも兼ねて書いているので、これから TypeScript を学ぶ人の参考になれば嬉しいです。

typeinterfaceの共通点
  • どちらも 型を定義するために使える
  • オブジェクトの形を表したり、再利用性を高めることができる

一見すると「どっちを使っても同じじゃない?」と思うかもしれませんが、実は特徴が少し違います。

typeの特徴
  • ユニオン型やプリミティブ型のエイリアスに使える
  • &(インターセクション)を使えば型を合成できる
  • ただし 宣言マージはできない

例:ユニオン型の定義

export type AccountingType = 
  | "収入" 
  | "支出(現金)" 
  | "支出(クレジットカード)";

この場合、AccountingType は 3つの文字列のどれか を意味します。

interfaceの特徴
  • 主にオブジェクトの形を表現するのに使う
  • extends で他のインターフェースを継承できる
  • 宣言マージが可能 → 後から同じ名前で再定義すると自動で結合される

例:オブジェクト型の定義

export interface Accounting {
  id: string;
  date: string;
  amount: number;
  content: string;
  type: AccountingType;
  category: IncomeCategory | ExpenseCategory;
}
宣言マージの違い

interface の場合

同じ名前で再宣言すると自動で結合されます。

interface Accounting {
  id: string;
  amount: number;
}

// 後から拡張できる!
interface Accounting {
  memo: string;
}

const a: Accounting = {
  id: "1",
  amount: 1000,
  memo: "昼ごはん代"
};

あとから自由にフィールドを追加できるのが大きな特徴。

type の場合

同じ名前で再宣言はできません。

type Accounting = {
  id: string;
  amount: number;
};

// 再宣言するとエラー
// type Accounting = { memo: string };

// 拡張するなら & を使う
type AccountingWithMemo = Accounting & { memo: string };

const b: AccountingWithMemo = {
  id: "2",
  amount: 2000,
  memo: "家賃"
};

type は その場で閉じた型を作るイメージです。

ユニオン型とは?

ユニオン型は「どれかひとつ」を表す型です。
| を使います。

let value: string | number;

value = "こんにちは"; // OK
value = 123;         // OK
value = true;        // エラー

今回の例だと、IncomeCategory | ExpenseCategory がまさにユニオン型です。
「収入カテゴリ」か「支出カテゴリ」のどちらか、という意味になります。

まとめ

type

  • ユニオン型やプリミティブ型に強い
  • 拡張するときは & を使う

interface

  • オブジェクトの型を表すのに便利
  • 宣言マージがあるので後から拡張できる

ユニオン型

  • 「型の選択肢を列挙」できる便利な仕組み

僕の場合、

  • 固定的に使う型 → type
  • 将来拡張したい型 → interface

という感じで使い分けています。
TypeScript の型は慣れると本当に強力なので、ぜひいろいろ試してみてください。