ジェネリクス(Generics)

Generics(ジェネリクス)は、型をパラメータとして扱う仕組みです。
再利用可能かつ型安全な関数・クラス・型定義を実現できます。


✅ 基本構文

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

identity
<string>("hello"); // 明示指定
identity(42);              // 推論でも可
  • T は型のプレースホルダー(任意の名前が使用可能)
  • 呼び出し時に型を明示する or 推論される

🔍 関数での使用例

function toArray
<T>(value: T): T[] {
  return [value];
}

toArray
<number>(5); // [5]
toArray("hi");      // ["hi"]

🧱 ジェネリクスを使った型定義

type ApiResponse
<T> = {
  data: T;
  success: boolean;
};

const res: ApiResponse
<string> = {
  data: "OK",
  success: true,
};

🏗️ ジェネリクスクラス

class Box
<T> {
  constructor(public value: T) {}
  getValue(): T {
    return this.value;
  }
}

const stringBox = new Box
<string>("hello");
const numberBox = new Box(123); // 推論される

🎯 型制約(extends)

function logLength<T extends { length: number }>(arg: T): number {
  return arg.length;
}

logLength("hello");         // OK
logLength([1, 2, 3]);       // OK
// logLength(123);          // ❌ numberはlengthを持たない

🔄 複数型パラメータ

function merge<T, U>(obj1: T, obj2: U): T & U {
  return { ...obj1, ...obj2 };
}

const result = merge({ name: "Alice" }, { age: 30 });
// → { name: "Alice", age: 30 }

🎯 デフォルト型

type Response<T = string> = {
  data: T;
};

const res1: Response = { data: "OK" };       // Tはstring
const res2: Response
<number> = { data: 42 }; // Tはnumber

🧠 条件付き型と併用

type IsString
<T> = T extends string ? "Yes" : "No";

type A = IsString<"abc">; // "Yes"
type B = IsString
<123>;   // "No"

🧩 ジェネリクス + keyof

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

const person = { name: "Tom", age: 25 };
getProp(person, "name"); // OK
// getProp(person, "height"); // ❌ エラー

🚀 実践的な応用:ユーティリティ型の一部もGenerics

  • `Partial `
  • `Readonly `
  • Record<K, T>
  • Pick<T, K>
  • Omit<T, K>
  • `ReturnType `
  • `Parameters `

例:

type User = { id: number; name: string };
type PartialUser = Partial
<User>; // { id?: number; name?: string }

コメントを残す 0

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