関数の引数でジェネリクスを活用する例

関数の引数にジェネリクスを使うことで、「どんな型の値が来ても型安全に処理できる」「補完が効く」「再利用性が高い」など多くの利点があります。


✅ 目的:あらゆる型に対応できる関数を型安全に定義する

function echo
<T>(value: T): T {
  return value;
}

✅ 使用例

echo("hello");       // string → string
echo(123);           // number → number
echo({ id: 1 });     // { id: number } → { id: number }
  • value: T に与えた型がそのまま戻り値に反映される
  • 型キャスト不要、any不使用でも型安全

📌 固定型との比較

function echoString(value: string): string {
  return value;
}

echoString("hi");   // OK
echoString(42);     // ❌ エラー
  • 固定型では 型が1つに縛られてしまい、使い回しできない

🧩 実践例:配列の先頭を取得する関数

❌ anyを使ったバージョン(型安全でない)

function getFirst(arr: any[]): any {
  return arr[0];
}

const result = getFirst(["a", "b", "c"]); // result: any
result.toUpperCase(); // ❌ コンパイル通るが実行時エラーの恐れ

✅ ジェネリクスで型安全に

function getFirst
<T>(arr: T[]): T | undefined {
  return arr[0];
}

const s = getFirst(["a", "b", "c"]); // string
const n = getFirst([1, 2, 3]);       // number
  • 戻り値の型が引数の中身に連動
  • IDE補完も正しく効く
  • undefined も正しく型として表現できる

🎯 キー制限付き引数に使う

function getProp<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

const user = { id: 1, name: "Tom" };

getProp(user, "name"); // OK → string
getProp(user, "id");   // OK → number
// getProp(user, "email"); // ❌ エラー: email は存在しないキー
  • 引数に存在するキーしか渡せない
  • 戻り値の型が動的に変わる(型安全!)

✅ 関数引数でのジェネリクスの嬉しいポイントまとめ

ポイント 内容
✅ 型安全 any を使わず、渡された型に応じた処理ができる
✅ 再利用性 一度定義すれば複数の型に使い回せる
✅ 補完が効く IDEで引数や戻り値に対して正確な補完が出る
✅ 制約を加えられる extends によって構造的な制限を加えられる

📚 まとめ:関数 × ジェネリクスが向いている場面

  • データ型が呼び出し元によって変わる(配列・オブジェクトなど)
  • 共通の処理ロジックに複数の型を適用したい
  • IDE補完や型推論を最大限に活かしたい
  • keyofT[K] を使った安全な動的アクセスをしたい
function filterByProp<T, K extends keyof T>(
  list: T[],
  key: K,
  value: T[K]
): T[] {
  return list.filter(item => item[key] === value);
}

このように、関数の引数でジェネリクスを使うことで、「安全で柔軟」なコードが書けるようになります。

コメントを残す 0

Your email address will not be published. Required fields are marked *