はじめに
前回
TypeScriptの型システムは非常に表現力が高く、柔軟である。
しかし、その多様さゆえに「どの型定義方法を使うべきか」で悩む場面も多い。
本稿では、以下3つの型定義手法について詳しく解説する:
- 型エイリアス(
type) - インターフェース(
interface) - 交差型(Intersection Type)
それぞれの使い分けや設計指針を示しつつ、実務的な設計のヒントを提示する。
型エイリアス(type)
型エイリアスは、任意の型に名前を付ける構文である。
type UserId = string;
type Point = { x: number; y: number };
特徴:
- プリミティブ型、ユニオン型、交差型、ジェネリクスなど何でも定義可能
- 複雑な型を再利用しやすくなる
型の組み合わせによる柔軟な記述に適している。
type Status = "draft" | "published" | "archived";
type Post = {
id: number;
title: string;
status: Status;
};
インターフェース(interface)
インターフェースは、オブジェクトの構造を定義するための専用構文である。
interface User {
id: number;
name: string;
}
特徴:
- オブジェクトの設計に特化
- 拡張(
extends)が可能 - クラスとの親和性が高い
interface Admin extends User {
role: "admin" | "superadmin";
}
インターフェースは拡張を前提とした設計で、型システムの「階層化」に向いている。
交差型(Intersection Type)
交差型は、複数の型を合成する構文である。
type Timestamped = { createdAt: Date; updatedAt: Date };
type Post = { title: string } & Timestamped;
特徴:
- 型の合成ができる
- 継承とは異なり、複数の型を統合可能
- 型の共通項を抽出しやすい
使いすぎると型の読解性が下がるため、意図的に用いる必要がある。
どれを使うべきか?
| 用途 | 推奨型 |
|---|---|
| プリミティブやユニオン型の再利用 | type |
| クラスや階層構造、ドメインモデル | interface |
| 複数型のマージ |
&(交差型) |
実務では、type と interface を適材適所で使い分けることが鍵となる。
また、最近のTypeScriptでは interface より type の方が柔軟な記述を可能にするケースも多いため、設計思想とプロジェクト方針に合わせて統一することが望ましい。
補足:補完の違い
VSCodeなどの補完ツールにおいて、interface の方が補完精度が高いという声もある。
一方で、type は構文的な自由度が高く、ユニオン・交差型の組み合わせにも強い。
したがって、設計対象が「拡張されることを前提とした構造」かどうかで選定するのが基本方針となる。
まとめ
TypeScriptの型定義は「読みやすさ」と「安全性」と「拡張性」のバランスである。
-
type:柔軟性と簡潔さを重視した記述に適している -
interface:構造化と拡張性に優れ、ドメインモデルに向いている -
&:型の再利用・統合において強力な手段
最終的な目的は「読みやすく、安全で、壊れにくいコード」である。
その目的のために、型定義もまた戦略的に設計されるべきである。
次回は「TypeScriptにおける制御フロー解析と型の絞り込み」をテーマに、より精緻な型の活用術を深掘りしていく。