TypeScriptのジェネリクスってなに?
TypeScriptのジェネリクス(Generics)は、再利用可能なコードを作成するための機能で、特定の型に依存しない柔軟な関数やクラス、インターフェースを定義することができます。ジェネリクスを使うと、同じロジックをさまざまな型に対して適用でき、型安全性を維持しながらコードの汎用性を高めることができます。
ジェネリクスの基本
ジェネリクスは、関数やクラスを定義する際に 型パラメータ を使用します。この型パラメータは、具体的な型が指定されるまで抽象的であり、関数やクラスを呼び出すときに具体的な型が与えられます。
具体的な記載はこんな感じ
function identity<T>(arg: T): T {
return arg;
}
この関数は引数 arg の型をジェネリック型 T として宣言しています。T は呼び出し時に具体的な型に置き換わります。つまりstringでもnumberでもどんな型でも可能ということですね。
const result1 = identity<string>("Hello");
const result2 = identity<number>(123);
identity("Hello") の場合、型 T は string に置き換わり、関数は string 型の引数を受け取り、string 型を返します。
identity(123) の場合は、T は number に置き換わります。
型推論
ジェネリクスは、TypeScriptの型推論によって、型を明示的に指定しなくても自動的に推測される場合があります。
const result3 = identity("TypeScript"); //
型推論により、明言せずともT は string になります。
ジェネリックの活用例
ジェネリクスを使って、どんな型の配列でも処理できる関数を作成できます。
function getArrayItem<T>(arr: T[], index: number): T {
return arr[index];
}
const numbers = [1, 2, 3, 4];
const words = ["hello", "world"];
const num = getArrayItem(numbers, 2); // 型は number
const word = getArrayItem(words, 1); // 型は string
getArrayItem<number>(numbers, 2)
では T が number となり、関数は number 型の配列の要素を返します。
同様に getArrayItem<string>(words, 1)
では T が string となります。
また、クラスやインターフェースにもジェネリクスを適用できます。
interface Pair<K, V> {
key: K;
value: V;
}
const stringNumberPair: Pair<string, number> = { key: "age", value: 30 };
const booleanStringPair: Pair<boolean, string> = { key: true, value: "yes" };
Pair<string, number>
は key が string で、value が number というペアを定義します。
Pair<boolean, string>
は、key が boolean で、value が string というペアです。