TypeScriptのtypeエイリアスとは?基本の書き方と使いどころを整理する
TypeScriptでオブジェクトに型を付けようとすると、interfaceとtypeという2種類の書き方が出てきますよね。
typeって何をするためのもの?interfaceと何が違うの?
typeの書き方は見かけるけど、どこで使えばいいかよくわからない…
interfaceとtype、どちらで書けばいいか毎回迷ってしまう
この記事では、TypeScriptのtype(typeエイリアス)が「何者か」という基本的な概念から、実際の書き方・使いどころまで順番に説明します。
この記事は次のような方におすすめです。
- TypeScriptの
typeがよくわからない方 typeの基本的な書き方を知りたい方typeはオブジェクトの型定義だけに使うものだと思っていた方- string・numberなどのプリミティブ型はなんとなくわかってきた段階の方
この記事を読み終えると、typeエイリアスの概念・書き方・使いどころがひととおりわかるようになります。「typeで何が書けるか」をコード例で確認しながら進められるので、ぜひ手を動かして試してみてください。
それでは、順を追って詳しく見ていきましょう!
- 未経験で後悔したくない
【実体験】未経験からITエンジニアに転職して後悔した話|4社経験してわかった「最初の選択ミス」 - 年収が低くて不安
4年間ずっと年収260万だったエンジニアが、転職で510万になるまでの全記録
typeエイリアスって何?「型に名前をつける」しくみ
typeエイリアスとは、型に名前をつけて、その名前で型を使い回せるようにする仕組みです。「エイリアス(alias)」は「別名」という意味で、「型に別の名前をつける機能」だと考えるとイメージがしやすいです。
言葉だけだとわかりにくいので、まず基本構文から見ていきましょう。
typeキーワードで型を定義する基本構文
typeエイリアスはtypeキーワードを使って次のように書きます。
type 型名 = 型;
たとえば、string型にUserNameという名前をつけるとこうなります。
type UserName = string;
これで「UserNameはstringと同じ」という定義ができました。あとは変数や関数の型としてUserNameを使えます。
type UserName = string;
const name: UserName = "田中"; // UserName は string なので string の値を入れられる
UserNameと書いても、stringと書いても、TypeScriptからは同じ型として扱われます。
「エイリアス(別名)」という言葉の意味
ここで「エイリアス」という言葉を少し掘り下げておきます。
typeエイリアスは、型そのものを新しく作るのではなく、既存の型に名前をつけているだけです。つまり、UserNameという新しい型が誕生するわけではなく、「stringをUserNameという名前でも呼べるようにした」という状態になります。
この感覚は最初はちょっとわかりにくいかもしれません。でも「エイリアス=型の別名」と覚えておけば、あとの説明がスムーズに入ってきます。
typeエイリアスでオブジェクト型を定義する
typeエイリアスは、プリミティブ型の別名だけでなく、オブジェクトの型定義にも使えます。interfaceと似た書き方で、オブジェクトの形(プロパティの名前と型)を定義できます。
基本の書き方と使い方
typeキーワードのあとに型名を書き、= {}の中にプロパティを列挙します。
type User = {
name: string;
age: number;
};
これで「name(string型)とage(number型)を持つオブジェクト」をUserという名前で定義できました。あとは変数や関数の引数に使えます。
type User = {
name: string;
age: number;
};
const user: User = { name: "田中", age: 25 };
function greet(user: User): string {
return `${user.name}さん、こんにちは!`;
}
型が合わない値を入れようとすれば、TypeScriptがすぐにエラーを出してくれます。型名をつけることで「このオブジェクトは何者か」がコードを読むだけでわかるようになるのも、typeエイリアスを使う利点のひとつです。
省略可能なプロパティの書き方(オプショナル)
プロパティ名のあとに?をつけると、「あってもなくてもいい」任意のプロパティを表現できます。
type User = {
name: string;
age: number;
email?: string; // あってもなくてもOK
};
const user1: User = { name: "田中", age: 25 }; // emailなしでもOK
const user2: User = { name: "鈴木", age: 30, email: "suzuki@example.com" }; // emailありもOK
email?と書くことで、emailはstringまたはundefined(存在しない)のどちらでも受け付けられるようになります。interfaceでもまったく同じ書き方ができます。
typeはオブジェクト以外にも使える
typeエイリアスの特徴として押さえておきたいのが、オブジェクトの型定義だけでなく、幅広い種類の型に名前をつけられることです。
ユニオン型に名前をつける
ユニオン型とは「このどれかの型」を表す書き方で、|(パイプ)でつないで定義します。
type Status = "active" | "inactive" | "pending";
const userStatus: Status = "active"; // OK
const userStatus2: Status = "deleted"; // エラー! Statusにない値は使えない
"active" | "inactive" | "pending"のどれかしか入れられない、という制約を型で表現できます。このユニオン型の定義はtypeでしかできず、interfaceでは書けません。
リテラル型に名前をつける
リテラル型とは、特定の値そのものを型として使う書き方です。ユニオン型との組み合わせでよく使われます。
type Direction = "up" | "down" | "left" | "right";
type HttpMethod = "GET" | "POST" | "PUT" | "DELETE";
これも同様にtypeでしか書けません。「決まった値のどれかしか使わせたくない」場面でよく登場します。
関数型に名前をつける
関数の型(引数と戻り値の型)にも、typeで名前をつけられます。
type Greeter = (name: string) => string;
const greet: Greeter = (name) => `${name}さん、こんにちは!`;
Greeterは「stringを受け取ってstringを返す関数」を表す型です。複数の箇所で同じ形の関数を使うとき、typeで名前をつけておくとコードがすっきりします。
typeエイリアスを使うと何がうれしいのか
ここまでtypeエイリアスの書き方を見てきました。では、型に名前をつけることでどんな恩恵があるのでしょうか。
一番のメリットは「型の再利用」です。たとえばUser型を複数の関数で使いたい場合、typeエイリアスがないと毎回{ name: string; age: number }と書くことになります。typeエイリアスで一度定義してしまえば、あとはUserと書くだけです。
// typeエイリアスなしの場合
function greet(user: { name: string; age: number }) { ... }
function showProfile(user: { name: string; age: number }) { ... }
function updateUser(user: { name: string; age: number }) { ... }
// typeエイリアスありの場合
type User = { name: string; age: number };
function greet(user: User) { ... }
function showProfile(user: User) { ... }
function updateUser(user: User) { ... }
同じ型を何度も書く必要がなくなり、後から「ageの型を変えたい」となってもUserの定義を1か所直すだけで済みます。
もうひとつのメリットは「コードの読みやすさ」です。{ name: string; age: number }と書くよりもUserと書いたほうが、「このオブジェクトが何者か」が一目でわかります。型名がドキュメントの役割を果たしてくれるので、コードを読む人にとってもわかりやすくなります。
interfaceとの役割分担について
typeエイリアスをひととおり見てきたところで、interfaceとの役割分担を整理しておきます。
まず、ユニオン型・リテラル型はtypeを使う一択です。これらはinterfaceでは書けません。この記事で見てきたStatusやDirectionのような型はtypeでしか定義できません。
関数型については、typeのアロー構文((引数: 型) => 戻り値型)で書くのが一般的です。interfaceでもコールシグネチャという別の構文で定義できますが、読みやすさの面からtypeが選ばれることがほとんどです。
一方、オブジェクトの型定義に限っては、typeでもinterfaceでも同じことができます。どちらで書いても動作は変わりません。
ただし、interfaceの方が自然に感じる場面が2つあります。1つ目は、classにimplementsで型を適用するときです。2つ目は、既存の型定義をextendsで拡張するときです。interfaceのextendsはパフォーマンス上の利点もあり、型の継承関係を明示したいケースではinterfaceが選ばれやすいです。
それ以外のオブジェクト型定義については、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プログラマーになれるはずです。
まとめ — typeエイリアスの書き方と使いどころ
この記事で説明した内容を振り返ります。
- typeエイリアスとは、型に名前をつけて使い回せるようにする仕組み
type 型名 = 型;という形で書く- オブジェクトの型定義もtypeで書ける(interfaceと似た書き方)
- プロパティに
?をつけるとオプショナル(任意)になる - ユニオン型・リテラル型はtypeでしか書けない。関数型はtypeのアロー構文で書くのが一般的(interfaceでもコールシグネチャ構文で定義できる)
- 型に名前をつけることで、型の再利用ができ、コードが読みやすくなる
- オブジェクト型定義はどちらでも書けるが、classへの
implementsやextendsによる拡張はinterfaceが自然
typeエイリアスはTypeScriptを書くうえでよく登場する書き方です。まずはオブジェクト型の定義から慣れていき、ユニオン型やリテラル型との組み合わせに少しずつ挑戦してみてください。
typeの基本が掴めたら、次は「interfaceとtypeの3つの違いと使い分け」を確認しておくと、コードを書くときの判断が楽になります。
※本記事の本文案はAIを活用して作成していますが、記載している内容およびコードは筆者が実際に調査、検証・実行し、内容の正確性を確認した上で公開しています。





