ジェネリクスとは
ジェネリクスは、型を「変数」のように扱い、関数やクラスを汎用的にする仕組み。特定の型に縛られず、型安全を保ちながらコードを再利用可能に。
function identity<T>(str: T): T {
return str;
}
const str: string = identity("Hello"); // Tはstring
const num: number = identity(42); // Tはnumber
ポイント: <T>
で型を動的に定義。入力と出力の型を一致させる。
なぜジェネリクスを使うか
- 型安全: 型を指定し、エラーを防ぐ。
- 再利用性: 1つの関数で複数の型に対応。
- Next.jsでの活用: APIレスポンスやPropsの型を柔軟に扱う。
例:配列の最初の要素を返す関数。
function getFirst<T>(items: T[]): T {
return items[0];
}
const firstStr: string = getFirst(["a", "b"]); // "a"
const firstNum: number = getFirst([1, 2, 3]); // 1
ポイント: 配列の型を動的に扱い、型推論で安全に。
型制約(extends)
ジェネリクスの型に制限を加える。
function printLength<T extends { length: number }>(item: T): number {
return item.length;
}
console.log(printLength("Hello")); // 5
console.log(printLength([1, 2, 3])); // 3
// console.log(printLength(42)); // エラー:lengthがない
ポイント: extends
でlength
プロパティを要求。Next.jsのフォームデータ(文字列や配列)に便利。
複数の型パラメータ
複数の型を扱う。
function merge<T, U>(a: T, b: U): [T, U] {
return [a, b];
}
const result: [string, number] = merge("Taro", 25); // ["Taro", 25]
ポイント: <T, U>
で複数型を定義。Next.jsのAPIで異なるデータ型をペアで返す場合に有効。
インターフェースとジェネリクス
インターフェースにジェネリクスを適用。
interface Response<T> {
data: T;
status: string;
}
const userResponse: Response<{ name: string }> = {
data: { name: "Taro" },
status: "success",
};
ポイント: Response<T>
でデータ型を動的に。Next.jsのAPIレスポンス型に最適。
クラスとジェネリクス
クラスで汎用的なデータ処理。
class DataStore<T> {
private items: T[] = [];
add(item: T): void {
this.items.push(item);
}
getAll(): T[] {
return this.items;
}
}
const numberStore = new DataStore<number>();
numberStore.add(1);
console.log(numberStore.getAll()); // [1]
ポイント: クラスで型を再利用。Next.jsの状態管理やデータキャッシュに活用。
まとめ
ジェネリクスは型をパラメータ化して再利用可能で型安全なコードを実現する機能。関数、インターフェース、クラスで使用でき、Web開発(例:Next.js)でAPIやコンポーネントの型安全性を高める。