【じぇねりくす】

ジェネリクス とは?

最終更新:
💡 型の対応関係を保ちながら、コードを再利用する

型をパラメータとして受け取り、型安全を保ちながら様々な型に対応できる汎用的なコード(関数・クラス・インターフェース)を書くための仕組み。

📌 このページのポイント
型パラメータを具体的な型へ Box<T> value: T Box<string> "hello" Box<number> 42 Box<User> Userの値 入力と出力の型の関係を保つ 型の指定だけでは実行時の検査はしない
TypeScriptの例。Boxの同じ構造を使い、valueの型を指定する。
ひよこ ひよこ
ジェネリクスって何で必要なの?
ペンギン先生 ペンギン先生
数値にも文字列にも、受け取った値をそのまま返す処理を使いたいとしよう。TypeScriptなら「function identity<T>(value: T): T」を定義して、入力と出力の型を結び付けられるよ。型ごとに同じ処理を別々に書かずに済むんだ。
ひよこ ひよこ
anyを使えばいいんじゃないの?
ペンギン先生 ペンギン先生
anyだと、その値についての型チェックを回避できてしまうよ。ジェネリクスなら、入力がstringなら戻り値もstring、といった対応を保てる。使える型を広げながら、型の情報を残すことが中心なんだ。
ひよこ ひよこ
Array<T>のTって何?
ペンギン先生 ペンギン先生
型パラメータで、使うときの型を受け取る変数のようなものだよ。Array<number>なら数値の配列、Array<string>なら文字列の配列。Tという名前は例で、Typeなど別の名前も使えるんだ。
ひよこ ひよこ
型パラメータに制約をつけるってどういうこと?
ペンギン先生 ペンギン先生
TypeScriptで「T extends Lengthwise」と書き、Lengthwiseに数値のlengthを定義すれば、その性質を持つ型を受け付けられるよ。明示的に同じインターフェースを実装すると宣言した型だけ、という制限ではないんだ。
ひよこ ひよこ
実行するときもTが入力を検査してくれる?
ペンギン先生 ペンギン先生
TypeScriptの型の注釈はJavaScriptへの変換で消えるよ。ジェネリクスだけでは外部から来たデータを実行時に検査できない。必要なら、実際の値を確かめる処理を別に用意するんだ。他の言語での実装方式まで同じとは限らないよ。
もっと詳しく知りたい人へ

配列の先頭を返すジェネリック関数は、いつもTを返せる?

空配列なら要素がなく、undefinedになる場合がある。ジェネリクスはその可能性を消す仕組みではない。T | undefinedを返す設計や、空でない配列だけを受け付ける設計など、関数の入力条件と戻り値を合わせる必要がある。

ペンギン
まとめ:ざっくりこれだけ覚えればOK!
「ジェネリクス」って出てきたら「型をパラメータにしてコードを再利用する仕組み」と思えばだいたいOK!
📖 おまけ:英語の意味
「Generics」 = 汎用的な・一般的な
💬 特定の型だけに固定せず、型をパラメータにしたコードを使える、という意味で捉えると分かりやすいよ

参考資料

← 用語集にもどる