こんにちは!フロントエンド・アーキテクチャの世界へようこそ。
TypeScriptを触りはじめると、「型があって安心!」と思える一方で、だんだんこんな風に思うことありませんか?
「あれ、似たような型の定義を何度も書いている気がする……」
「ここに渡すデータによって、型をいい感じにカメレオンみたいに変えられたら最高なのに!」
そう、型定義の「コピペ地獄」にハマりかけたそこのあなた。おめでとうございます、あなたは次のステップに進む扉の前に立っています。
今回は、そんなモヤモヤをスッキリ解消してくれる魔法のテクニック「ジェネリック・タイプ・エイリアス(型引数を受け取る型エイリアス)」について、身近な例えを交えながら優しく紐解いていきましょう。
大丈夫、難しくなんてありません。一歩ずつ、一緒に見ていきましょうね!
—
1. まずはおさらい:型エイリアスと「型引数」のイメージ
そもそも「型エイリアス(`type`)」って覚えていますか?
これは、長かったり複雑だったりする型に、自分で「あだ名」をつける機能でしたよね。
// 文字列か数字が入るよ、というあだ名をつける例
type MyID = string | number;
さて、ここからが本題です。
日常生活をちょっと想像してみてください。例えば、スーパーで売っている「透明なプラスチックの保存容器」を思い浮かべてみてください。
あの容器そのものは「ただの箱」ですが、中に何を入れるかで役割が変わりますよね。
- 「クッキー」を入れたら、クッキー専用の容器になる。
- 「おにぎり」を入れたら、おにぎり専用の容器になる。
TypeScriptのジェネリクス(型引数)も、まさにこれと全く同じなんです!
「型を入れるための空っぽのBOX」を作っておいて、使うときに「今回はこれを入れてね!」と指示を出す仕組みのことです。
—
2. 実際に書いてみよう:お弁当箱の例え
百聞は一見に如かず。コードを見てみましょう。
例えば、Webアプリを作っていると、「APIから返ってきたデータ」を包み込むような「包み紙(レスポンス用の型)」をよく作ります。
ここで、どんなデータ(ユーザー情報かもしれないし、記事のリストかもしれない)が来ても対応できる「便利な包み紙」を作ってみましょう。
/
- どんな中身でも包める「魔法の包み紙」の型
- `
` の部分が「型引数(空っぽのBOX)」です。Tは Type(型)の頭文字だよ!
/
type ApiResponse
status: number; // ステータスコード(200とか404とか)
message: string; // メッセージ
data: T; // ★ここがミソ!「T」という可変のデータが入る
};
見てください、この `T` という文字。これが「型を受け取るための穴」です。
では、実際にこの魔法の包み紙を使ってみましょう!
ユーザー情報を包む場合
// ユーザー情報の型をあらかじめ定義しておきます
type User = {
id: number;
name: string;
};
// 1. ユーザー情報を包んだAPIレスポンスの型を作る
type UserResponse = ApiResponse
// 実際に使ってみるよ
const myResponse: UserResponse = {
status: 200,
message: “成功しました!”,
data: {
id: 1,
name: “山田太郎” // きちんと User の型が適用されます!
}
};
今度は「商品リスト」を包んでみるよ
同じ `ApiResponse` という型なのに、今度は中身を「商品の配列」に変えてみます。
type Product = {
productId: string;
price: number;
};
// 2. 商品の配列を包んだAPIレスポンスの型を作る
type ProductListResponse = ApiResponse
// 使ってみる
const shopResponse: ProductListResponse = {
status: 200,
message: “商品の取得に成功しました”,
data: [
{ productId: “p-001”, price: 1200 },
{ productId: “p-002”, price: 3000 }
// 中身が Product[] なので、おかしなデータを入れようとするとTypeScriptが怒ってくれます
]
};
すごくないですか?
`ApiResponse` という一つの定義を使い回しながら、渡す型(`User` や `Product[]`)を変えるだけで、まったく別の専用型が動的に生まれているんです。これがジェネリック・タイプ・エイリアスの実力です!
—
3. つまずきやすいポイントと、優しく寄り添うアドバイス
初学者の頃、多くの人がここでちょっと混乱します。
> 「`
大丈夫、安心してください!
`T` という文字は、ただの「仮の名前(変数名)」です。数学の `x` や `y` と同じだと思ってください。
実は、何でも好きな名前をつけていいんです。
// T じゃなくて、わかりやすく Item でも全然OK!
type Box
value: Item;
};
最初は `T` や `Data` など、自分が「あ、これだな」としっくりくる名前をつけてあげればバッチリですよ。
—
4. 実務でよく使う!ちょっと便利な応用例
最後に、実際のWeb制作やアプリ開発の現場で「おっ、これ便利だな」とよく使われるパターンをもう一つご紹介しますね。
例えば、フォームの入力値や、設定値のように、「すべてのプロパティがオプショナル(任意)になった状態の型」をサクッと作りたいとき、ジェネリクスを使うとこう書けます。
// すべての項目を「未入力でもOK(?:)」にする魔法の型
type PartialState
[K in keyof T]?: T[K];
};
// ユーザーの初期設定
type UserSettings = {
theme: string;
notifications: boolean;
};
// 「一部の項目だけ変えたい!」というとき、このジェネリクスが使えます
type UpdateSettings = PartialState
/
出来上がる型は実質これと同じ!:
{
theme?: string;
notifications?: boolean;
}
/
(※ちなみにTypeScriptには最初から `Partial
—
まとめ
いかがでしたでしょうか?
- 型エイリアスにおけるジェネリクスとは、型定義における「使い回せるお弁当箱(型引数 `
`)」のこと。 - 使うときに中身の型を教えるだけで、動的にぴったりの型を生成してくれる。
- `T` はただの仮の名前なので、怖がらなくて大丈夫!
「同じような型を何度も作っちゃっているな……」と感じたら、ぜひこのジェネリクスを思い出してみてください。あなたのコードが、ぐっとスマートに、そして優しく生まれ変わるはずです。
それでは、また次回のアーキテクチャ談議でお会いしましょう!Happy Coding!

コメント