モジュールのレッスン (2/2)
ファンダメンタルズジェネリック
ジェネリック (ジェネリック プログラミング) は、TypeScript の最も強力な機能の 1 つです。これにより、最大限の型安全性を維持し、any の使用を回避しながら、さまざまなデータ型を処理できる、柔軟で再利用可能なコンポーネント、関数、インターフェイスを作成できます。
汎用関数
ジェネリックは型の変数と考えてください。引数として渡された値を返す関数を考えてみましょう。
function identity<T>(arg: T): T {
return arg;
}文字 T (Type の略) は、タイプのプレースホルダーです。 identity を呼び出すと、TypeScript は渡された引数の型を取得し、T をその型に自動的に設定します。
const str = identity<string>('Hello'); // T is string
const num = identity(42); // T is number (automatically inferred!)汎用インターフェイスとエイリアス
ジェネリックスをインターフェイスや型エイリアスに適用して、ジェネリック コンテナーやデータ構造を定義することもできます。
interface Box<T> {
content: T;
}
const stringBox: Box<string> = { content: 'TypeScript' };
const numberBox: Box<number> = { content: 42 };複数の型パラメータ
複数の型変数を使用する関数または型を定義できます (T や U など)。
function mergeObjects<T, U>(obj1: T, obj2: U): T & U {
return { ...obj1, ...obj2 };
}一般的な制約
場合によっては、ジェネリックで受け入れられる型を制限したいことがあります。 extends キーワードを使用して制約を追加できます。
たとえば、ジェネリック型に常に length プロパティ (文字列や配列など) を持たせたい場合は、次のようにします。
interface HasLength {
length: number;
}
function logLength<T extends HasLength>(arg: T): void {
console.log(arg.length); // Safe! We know arg has 'length'
}
logLength('Hello'); // Valid
logLength([1, 2, 3]); // Valid
// logLength(42); // Error: number does not have a length property!自分で試してみてください
演習 1: 汎用恒等関数
ジェネリック ID 関数を完成させて、ジェネリック型 T の値パラメータを受け入れ、それを変更せずに返すようにします。
ヒントを表示
戻り値の型は、パラメーターと同じジェネリック型 T である必要があります。
3 回の試行後に解決策が利用可能になります
演習 2: 汎用ボックス ラッパー
型パラメーター T を受け取り、型 T の content という名前の単一のプロパティを持つ、Box という名前の汎用インターフェイスを定義します。
ヒントを表示
インターフェイス Box<T> { content: T; を使用します。 } 構文。
3 回の試行後に解決策が利用可能になります
演習 3: 一般的な制約
パラメーター arg を受け取る getLength という名前の汎用関数を作成します。 arg は、長さプロパティ (数値) を持つインターフェイスに制限する必要があります。関数は arg.length を返す必要があります。
ヒントを表示
関数を getLength<T extends HasLength>(arg: T):number として宣言し、arg.length を返します。
3 回の試行後に解決策が利用可能になります
演習 4: ジェネリックペア
1 番目の型 T と 2 番目の型 U の 2 つのプロパティを使用して、ジェネリック インターフェイス Pie<T, U> を定義します。 次に、1 番目 (T 型) と 2 番目 (U 型) を受け入れ、Pair<T, U> を実装するオブジェクトを返すジェネリック関数 makePair を作成します。
ヒントを表示
2 つの汎用パラメーターの構文を使用して、それに応じて makePair を定義します。
3 回の試行後に解決策が利用可能になります