TypeScriptにおけるイベント駆動型プログラミング:インターフェース、デコレータ、その他のテクニック
TypeScriptにおけるクラスのイベントサポート
TypeScriptでは、以下の2つの主要な方法でクラスでイベントをサポートすることができます。
- インターフェース: イベントを定義するインターフェースを作成することができます。このインターフェースには、イベント名とイベント引数の型を定義するプロパティが含まれます。クラスは、このインターフェースを実装することで、イベントをサポートすることができます。
interface ButtonEvent {
type: string; // "click" | "hover" など
}
class Button {
private onClickListeners: ((event: ButtonEvent) => void)[] = [];
addEventListener(type: string, listener: (event: ButtonEvent) => void) {
if (type === "click") {
this.onClickListeners.push(listener);
}
}
removeEventListener(type: string, listener: (event: ButtonEvent) => void) {
if (type === "click") {
this.onClickListeners = this.onClickListeners.filter(l => l !== listener);
}
}
click() {
const event: ButtonEvent = { type: "click" };
this.onClickListeners.forEach(listener => listener(event));
}
}
- デコレータ: イベントハンドラをクラスのメソッドとして定義し、デコレータを使用してイベントと関連付けることができます。
class Button {
@click
click() {
console.log("ボタンがクリックされました。");
}
}
function click(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
descriptor.value = function (...args: any[]) {
this.dispatchEvent(new CustomEvent(propertyKey, { detail: args }));
return descriptor.value.apply(this, args);
};
}
この例では、@click
デコレータは、click
メソッドがclick
イベントを発行することを示します。
- イベントの使用方法については、使用するライブラリまたはフレームワークのドキュメントを参照してください。
- 多くのライブラリとフレームワークは、独自のイベントシステムを提供しています。
- TypeScriptには、イベントを発行および処理するための組み込みのユーティリティはありません。
この例では、Button
クラスがclick
イベントを発行する方法を示します。
interface ButtonEvent {
type: string; // "click"
}
class Button {
private onClickListeners: ((event: ButtonEvent) => void)[] = [];
addEventListener(listener: (event: ButtonEvent) => void) {
this.onClickListeners.push(listener);
}
removeEventListener(listener: (event: ButtonEvent) => void) {
this.onClickListeners = this.onClickListeners.filter(l => l !== listener);
}
click() {
const event: ButtonEvent = { type: "click" };
this.onClickListeners.forEach(listener => listener(event));
}
}
const button = new Button();
button.addEventListener((event) => {
console.log("ボタンがクリックされました!");
});
button.click(); // ボタンがクリックされると、イベントハンドラが呼び出されます。
デコレータを使用したイベントサポート
class Button {
@click
click() {
console.log("ボタンがクリックされました。");
this.dispatchEvent(new CustomEvent("click"));
}
}
function click(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
descriptor.value = function (...args: any[]) {
this.dispatchEvent(new CustomEvent(propertyKey, { detail: args }));
return descriptor.value.apply(this, args);
};
}
const button = new Button();
button.addEventListener("click", () => {
console.log("デコレータを使用したイベントハンドラが呼び出されました。");
});
button.click(); // ボタンがクリックされると、イベントハンドラが呼び出されます。
説明:
- デコレータを使用すると、イベントハンドラをより簡潔に記述できます。
- リスナーは、イベントが発生したときに呼び出されます。
- リスナーは、
addEventListener
メソッドを使用してイベントに登録できます。
カスタムイベント
addEventListener
およびremoveEventListener
メソッドを使用して、イベントリスナーを登録および解除できます。dispatchEvent
メソッドを使用して、イベントをターゲットから発行できます。- カスタムイベントは、イベント名とオプションのイベントデータを含むオブジェクトとして作成されます。
CustomEvent
インターフェースを使用して、独自のカスタムイベントを作成できます。これは、特定のニーズに合わせた柔軟性を提供します。
静的メンバーとコールバック
- この方法は、基本的なイベントシステムに適していますが、より複雑なシナリオにはスケーラビリティが低くなります。
- 静的メンバーは、イベントリスナーを格納するために使用できます。
- シンプルなイベントシステムの場合は、静的メンバーとコールバックを使用して実装できます。
typescript