TypeScriptでのジェネリクスの基本的な使い方

TypeScriptでのジェネリクスの基本的な使い方

投稿日: 2025年11月18日

学習振り返り
Tips
要約
  • TypeScriptのジェネリックは、型を変数のように扱い、関数や型を柔軟に再利用できる仕組みです。
  • 具体的な型を指定せずに型引数を使用し、型安全性と再利用性を高めることができます。
  • ジェネリックを用いることで、APIレスポンスなどの多様なデータ型に対しても安全にアクセスできるようになります。
音声で記事を再生
0:00

TypeScriptの型の扱い方について、ジェネリクスという概念の実装があります。個人的にはちょっと複雑なロジックだし、キャッチアップ時期にはあんまり深入りしなくていいかなと敬遠していましたが、課題を進めていてこのジェネリクスの恩恵に預かれそうだったのでちょっと調べてまとめてみました。(間違ってたら教えてください💦)

ジェネリクスとは?

ジェネリクスは、型を変数や引数のように扱う仕組みです。(ジェネリックと言ったもりします。)関数や型定義を書くときに、具体的な型を決めずに「後で指定する」ことができます。

基本的なイメージ

// ❌ ジェネリクスなし:毎回新しい関数を書く必要がある
function getStringValue(): string {
  return "hello";
}

function getNumberValue(): number {
  return 42;
}

// ✅ ジェネリクスあり:1つの関数で全ての型に対応
function getValue<T>(): T {
  // Tは型引数。後で具体的な型が入る
  return someValue as T;
}

ジェネリクスの構文

基本的には関数、型、クラスそれぞれの宣言では、下記のように書きます。

// 関数
function functionName<T>(param: T): T {
  return param;
}

// 型
type MyType<T> = {
  value: T;
  getValue: () => T;
};

// クラス
class Container<T> {
  constructor(private item: T) {}
  getItem(): T {
    return this.item;
  }
}

実際の例

例1:配列を返す関数

// ❌ ジェネリクスなし
function getUsers(): User[] {
  // ...
}

function getPosts(): Post[] {
  // ...
}

// ✅ ジェネリクスあり:1つで全てに対応
function getItems<T>(endpoint: string): T[] {
  // endpointから取得して、T[]型で返す
}

// 使い方
const users = getItems<User>("/api/users");     // User[]が返される
const posts = getItems<Post>("/api/posts");     // Post[]が返される

例2:APIレスポンス

こちらは、今回私が直面した例です。APIレスポンスのデータ型がエンドポイントごとに異なるため、any型とするか、可能性がある全ての型をで繋げて許容する形で実装していました。
any型だと型チェックが行われないので型安全ではないため推奨されません❌。想定される全ての型を許容する例だと他のコンポーネントで呼び出す際に複数指定されている型のうちどれで型チェックすればいいのかTSが判断できずにエラーになります。

柔軟に扱いたい型の場所に型引数Tを置き、実際に型指定するときに<>内で指定してあげることができます。

// ジェネリクスなしの場合
type ApiResponse = {
  status: string;
  data: any;  // ❌ anyは危険(型チェックなし)
};

// ジェネリクスありの場合
type ApiResponse<T> = {
  status: string;
  data: T;    // ✅ T は呼び出し時に決まる
};

// 使い方
type UserResponse = ApiResponse<User>;      // data: User
type PostResponse = ApiResponse<Post>;      // data: Post
type CategoryResponse = ApiResponse<Category[]>;  // data: Category[]

備考

ジェネリクスのメリット

  • 型安全性…Union型ではなく、正確な型を指定できる。

  • 再利用性…1つの関数で複数の型に対応

  • 自動補完…エディタが正確にプロパティを提案

  • エラー検出…間違ったプロパティアクセスは即座に検出

※Uinion型…「型Tまたは型U」のような表現ができる型。
※InterSection型…「型Tかつ型U」を意味する型。
↑もっと奥が深いので調べる余地ありですね。。

シェア!

XThreads
user
Shuhei
WEBエンジニアとして個人で働けるようにがんばります
Loading...
記事一覧に戻る
XThreads
0