ジェネリクス(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 }