TypeScriptの基礎 - 型エイリアス
概要
TypeScriptの型エイリアス (Type Alias) とは、type キーワードを使用して既存の型に別名を付ける機能である。
型エイリアスは新しい型を生成するのではなく、既存の型への参照に名前を付けることで、コードの可読性と再利用性を向上させる。
TypeScript 5.x系以降では、型エイリアスの活用範囲が大幅に拡大しており、以下に示すような型操作が可能になっている。
| 用途 | 説明 |
|---|---|
| 基本的な型エイリアス | プリミティブ型、ユニオン型、オブジェクト型に別名を付けて一貫した型定義を維持する。 |
交差型 (&) |
複数の型を結合して全プロパティを持つ型を生成する。 |
| Conditional Types | T extends U ? X : Y の構文で型の条件分岐を表現し、型レベルのロジックを実装できる。
|
| Mapped Types | 既存の型からプロパティを動的に変換した新しい型を生成する。 ( Partial、Pick、Omit 等のユーティリティ型もこの仕組みで実装されている)
|
| Template Literal Types | 文字列リテラル型のパターンベース推論を可能にし、URLパスやイベント名等の型安全な文字列定義に活用できる。 |
TypeScript 4.9で導入された satisfies 演算子と型エイリアスを組み合わせることにより、型安全性を保ちながら値の具体的な型情報を保持できる。
interface との使い分けとしては、オブジェクト型の定義には interface を使用し、
ユニオン型、タプル型、プリミティブ型のエイリアス等には type を使用するのが一般的な指針である。
2026年2月時点でTypeScript 5.9が安定版としてリリースされている。
TypeScript 6.0ベータでは strict: true のデフォルト化等の変更が行われており、Go言語で書き直されるTypeScript 7.0では最大10倍のコンパイル速度向上が見込まれている。
オブジェクト型とインターフェースの詳細については、TypeScriptの基礎 - オブジェクト型とインターフェースのページを参照すること。
typeによる型定義
type キーワードは、任意の型に対して別名を定義するために使用する。
プリミティブ型からオブジェクト型、ユニオン型、関数型まで、あらゆる型に対して型エイリアスを作成できる。
基本的な構文
型エイリアスの基本構文は以下の通りである。
type <型名> = <型記述>;
型名は PascalCase (先頭大文字) で命名することが慣例である。
一度定義した型エイリアスは、型注釈が必要なあらゆる箇所で使用できる。
同じ名前で型エイリアスを再宣言することはできない。
type User = { name: string };
type User = { email: string }; // エラー: Duplicate identifier 'User'.
プリミティブ型とユニオン型のエイリアス
プリミティブ型に型エイリアスを付与することにより、型の意味をコードで明示できる。
- プリミティブ型のエイリアス
type ID = string; type Age = number; type IsActive = boolean; function getUserId(): ID { return "user-123"; }
- ユニオン型に型エイリアスを付与する例
type StringOrNumber = number | string; type Status = "pending" | "completed" | "failed"; type HttpMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
複数の文字列リテラルを縦に並べる書き方も可能である。
これはリテラルの数が多い場合に可読性が向上する。
type FileFormat =
| "json"
| "xml"
| "csv"
| "yaml";
判別ユニオン型 (Discriminated Union) は、共通のリテラル型プロパティを持つユニオン型である。
TypeScriptはそのプロパティの値によって型を絞り込むことができる。
type Result = { success: true; data: string } | { success: false; error: string };
function handleResult(result: Result) {
if (result.success) {
console.log(result.data); // success が true の場合は data にアクセス可能
}
else {
console.log(result.error); // success が false の場合は error にアクセス可能
}
}
判別ユニオン型の型絞り込みの詳細は、TypeScriptの基礎 - 型の絞り込みのページを参照すること。
オブジェクト型のエイリアス
オブジェクトの構造を型エイリアスとして定義することにより、複数の箇所で同じ型定義を再利用できる。
- 基本的なオブジェクト型のエイリアスの例
type User = { id: string; name: string; email: string; age: number; }; type Product = { id: number; title: string; price: number; inStock: boolean; tags?: string[]; // ?を付けることでオプショナルプロパティになる };
- オブジェクト型はネストして定義することも可能である。
type Address = { street: string; city: string; country: string; }; type Customer = { name: string; address: Address; // 別の型エイリアスを参照する phone: string; };
- インデックスシグネチャを使用すると、任意のキー名を持つオブジェクト型を定義できる。
- 以下の例では、ジェネリクス型パラメータ
Tを使用して、値の型を柔軟に変更できる汎用的な辞書型を定義している。 type Dictionary<T> = { [key: string]: T; }; type NumberDict = Dictionary<number>; const scores: NumberDict = { Alice: 90, Bob: 85, Carol: 92, };
- 以下の例では、ジェネリクス型パラメータ
交差型 (&)
交差型 (Intersection Type) は、複数の型を & で結合し、全ての型のプロパティを持つ単一の型を作成する機能である。
type による型エイリアスと組み合わせて使用することが多い。
基本的な使用方法
交差型の基本構文は以下の通りである。
type Combined = Type1 & Type2;
交差型を使用すると、Type1 と Type2 の両方のプロパティを持つ型が作成される。
どちらの型のプロパティが欠けていてもコンパイルエラーとなる。
プロパティ同士が競合する場合、そのプロパティの型は両方の型を満たす必要があるため、never 型になることがある。
type A = { x: 1 };
type B = { x: 2 };
type C = A & B; // Cは { x: never } となる (1 かつ 2を満たす値は存在しない)
プロパティの型が競合する場合の交差型は実質使用不可能な型になるため、設計時に注意が必要である。
オブジェクト型の合成
交差型は、複数の独立した型を組み合わせて新しい複合型を作成する場面で活用する。
type BusinessPartner = {
businessName: string;
registrationNumber: string;
};
type Contact = {
email: string;
phone: string;
};
type Identity = {
firstName: string;
lastName: string;
};
// 3つの型を合成する
type Customer = BusinessPartner & Contact & Identity;
const customer: Customer = {
businessName: "Acme Inc",
registrationNumber: "12345",
email: "info@acme.com",
phone: "+1-555-1234",
firstName: "John",
lastName: "Doe",
};
上記の例のように、役割ごとに分割した型を交差型で合成することにより、型定義の責務を明確に分離できる。
各部品型は独立して再利用可能であるため、保守性も向上する。
交差型 と interface の extends は似た役割を持つが、以下の点で異なる。
| 方法 | 説明 |
|---|---|
| interfaceのextends | コンパイラがキャッシュするため高速に処理される。 |
typeの& |
使用のたびに計算が行われる可能性がある。 |
パフォーマンスを重視する場面では、interface の extends の使用を検討する。
interfaceとtypeの違い
TypeScriptでオブジェクト型を定義する方法として、interface と type の両方が使用できる。
どちらも似た用途で使用できるが、機能に違いがあるため、適切に使い分けることが重要である。
機能比較
下表に、interface と type の主な機能の違いを示す。
| 機能 | type | interface |
|---|---|---|
| Declaration Merging (宣言マージ) | 不可 | 可能 |
継承 (extends) |
不可 (& を使用) |
可能 |
| プリミティブ型の定義 | 可能 | 不可 |
| ユニオン型の定義 | 可能 | 不可 |
| タプル型の定義 | 可能 | 不可 |
| Mapped Types | 可能 | 不可 |
| Conditional Types | 可能 | 不可 |
Declaration Mergingとは、同じ名前の interface を複数回宣言した場合に自動的にマージされる機能である。
// interface は同名宣言で自動マージされる
interface User {
name: string;
}
interface User {
email: string;
}
// 結果: { name: string; email: string; } と同等
type では同名の再宣言はコンパイルエラーとなる。
type User = { name: string };
type User = { email: string }; // エラー : Duplicate identifier 'User'.
継承の構文の違いを以下に示す。
// interface による継承
interface Animal {
name: string;
}
interface Dog extends Animal {
breed: string;
}
// typeによる継承 (交差型を使用)
type Animal = { name: string };
type Dog = Animal & { breed: string };
どちらの方法でも、Dog型はnameとbreedの両方のプロパティを持つ。
使い分けの指針
interface と type の一般的な使い分けの指針を以下に示す。
| 区分 | 場面 | 説明 |
|---|---|---|
type を使用する場面
|
ユニオン型やインターセクション型を定義する場合 | "completed" | "failed"; のような型は type でのみ定義できる
|
| プリミティブ型にエイリアスを付与する場合 | type ID = string; のようなプリミティブ型への別名 | |
| タプル型を定義する場合 | type Pair = [string, number]; のような固定長の配列型 | |
| Mapped TypesやConditional Typesを使用する場合 | ジェネリクスを活用した高度な型定義 | |
interface を使用する場面
|
オブジェクトの構造を定義する場合 | クラスのメンバや関数の引数の構造を表す型定義 |
| クラスが実装する契約 (implements) を定義する場合 | class MyClass implements MyInterface のような使い方 | |
| Declaration Mergingが必要な場合 | ライブラリの型定義を拡張する場面等 |
一般的な指針として、オブジェクト型にはinterfaceを使用し、それ以外の型 (ユニオン型、プリミティブ型のエイリアス、タプル型等) には type を使用することが推奨される。
重要なのは一貫したルールをプロジェクト全体で統一して運用することである。
関連情報
- TypeScriptの基礎 - tsconfig.json
- TypeScriptの基礎 - 型注釈とプリミティブ型
- TypeScriptの基礎 - 型推論
- TypeScriptの基礎 - オブジェクト型とインターフェース
- TypeScriptの基礎 - 関数の型定義