TypeScript - ジェネリックインターフェース

こんにちは、未来のプログラミングスーパースター!今日は、TypeScriptの世界に飛び込み、最も強力な機能の一つであるジェネリックインターフェースを探求する旅に出ます。プログラミングが初めてであっても心配しないでください。私はあなたの親切なガイドであり、ステップバイステップで進めます。このレッスンの終わりには、あなたがどれだけ学んだかに驚くことでしょう!

TypeScript - Generic Interfaces

ジェネリックインターフェースとは?

ジェネリックインターフェースに踏み込む前に、まずTypeScriptにおけるインターフェースとは何か簡単に復習しましょう。インターフェースは、オブジェクトの構造を定義する契約のようなものです。オブジェクトが持つべきプロパティとメソッドを教えてくれます。

さて、これらのインターフェースをさらに柔軟にし、異なるデータ型と動作するようにしたらどうでしょうか。それがジェネリックインターフェースです!ジェネリックインターフェースは、さまざまなデータ型に対応できるインターフェースを作成できるようにし、コードを再利用性が高く多様なものにします。

基本的なジェネリックインターフェース

まずは簡単な例から始めましょう:

interface Box<T> {
contents: T;
}

let numberBox: Box<number> = { contents: 42 };
let stringBox: Box<string> = { contents: "Hello, TypeScript!" };

この例では、Boxはジェネリックインターフェースです。<T>は後で指定する型のプレースホルダーです。このインターフェースを使って、異なる型のアイテムを保持できるボックスを作成できます:

  • numberBoxは数値を保持するBoxです。
  • stringBoxは文字列を保持するBoxです。

すごくないですか?魔法のボックスのように、中に何を入れるかによって適応できるんです!

複数の型パラメータ

ジェネリックインターフェースは複数の型パラメータを持つことができます。例を見てみましょう:

interface Pair<T, U> {
first: T;
second: U;
}

let pair1: Pair<number, string> = { first: 1, second: "one" };
let pair2: Pair<boolean, Date> = { first: true, second: new Date() };

ここで、Pairは2つの型パラメータ、TUを持つジェネリックインターフェースです。これにより、異なる型のアイテムのペアを作成できるようになります。任意の2つの型のダイナミックなペアを作れるんです!

メソッドを持つジェネリックインターフェース

インターフェースにはメソッドも含めることができ、これらのメソッドはジェネリック型を使用できます。例を見てみましょう:

interface Reversible<T> {
data: T[];
reverse(): T[];
}

class NumberArray implements Reversible<number> {
constructor(public data: number[]) {}

reverse(): number[] {
return this.data.slice().reverse();
}
}

let numbers = new NumberArray([1, 2, 3, 4, 5]);
console.log(numbers.reverse()); // 出力: [5, 4, 3, 2, 1]

この例では、Reversibleはジェネリックインターフェースで、reverse()メソッドを含んでいます。NumberArrayクラスは数値のためこのインターフェースを実装しています。このアプローチの素晴らしいところは、文字列やオブジェクト、他の型に対しても簡単に同様のクラスを作成できることです!

ファンクション型としてのジェネリックインターフェース

次に、ジェネリックインターフェースを使ってファンクション型を記述する方法を見てみましょう。ここでは非常に興味深いことがあります!

interface Transformer<T, U> {
(input: T): U;
}

let stringToNumber: Transformer<string, number> = (input) => parseInt(input);

console.log(stringToNumber("42")); // 出力: 42

この例では、Transformerはファンクション型を記述するためのジェネリックインターフェースです。入力として型Tを受け取り、型Uの値を返します。それを使って、文字列を数値に変換するstringToNumberというファンクションを作成しています。

実世界の例:データプロセッサ

もう少し複雑な例を見てみましょう。実世界のプログラミングで遭遇する可能性のあるものです:

interface DataProcessor<T, U> {
processItem(item: T): U;
processArray(items: T[]): U[];
}

class StringToNumberProcessor implements DataProcessor<string, number> {
processItem(item: string): number {
return parseInt(item);
}

processArray(items: string[]): number[] {
return items.map(item => this.processItem(item));
}
}

let processor = new StringToNumberProcessor();
console.log(processor.processItem("42"));          // 出力: 42
console.log(processor.processArray(["1", "2", "3"])); // 出力: [1, 2, 3]

この例では、DataProcessorインターフェースは個々のアイテムやアイテムの配列を処理するメソッドを定義しています。StringToNumberProcessorクラスはこのインターフェースを実装し、文字列を数値に変換します。このパターンは、データをさまざまな方法で処理しながら型の安全性を保つ必要がある場合に非常に有用です。

結論

おめでとうございます!TypeScriptの旅で大きな一歩を踏み出しました。ジェネリックインターフェースは、異なるデータ型で動作できる柔軟で再利用可能なコードを書くための強力なツールです。練習は完璧を生みますので、これらの概念を自分のプロジェクトで実験してみてください。

以下に、私たちがカバーしたメソッドの簡単な参照表を示します:

メソッド 説明
interface Box<T> 任意の型を保持できるボックスのジェネリックインターフェースを作成
interface Pair<T, U> 異なる型のアイテムのペアを作成するジェネリックインターフェース
interface Reversible<T> 配列を反転するメソッドを持つジェネリックインターフェース
interface Transformer<T, U> 入力の型Tを型Uに変換するファンクションを記述するジェネリックインターフェース
interface DataProcessor<T, U> 個々のアイテムやアイテムの配列を処理するジェネリックインターフェース

引き続きコードを書き、学び続けてください。そして、TypeScriptの世界では、ジェネリックはあなたのスーパーパワーです!?‍♀️?‍♂️

Credits: Image by storyset