首页 > 解决方案 > 如何在 TypeScript 中实现发布订阅模式?

问题描述

我正在为我的游戏创建一个事件系统,我的代码目前如下所示:

export const enum ET { Collision, Dying, Damage }

type ActionCallback = (scene: Scene, event: GameEvent) => void;

subscribe(eventType: ET, callback: ActionCallback) {
  this.subscriptions[eventType].push(callback);
}

然后一些使用此函数的代码示例如下:

scene.events.subscribe(ET.Dying, handleEntityDeath);

handleEntityDeath = (scene: Scene, event: DyingEvent) => {
  scene.deleteEntity(event.entity);
}

问题是 TypeScript 无法编译并显示类似:event's type must be GameEvent and not DyingEvent.

基本上,我需要一种“链接”ET.Dying和的方法DyingEvent,但我不知道该怎么做。我想如果我能做到这一点,那么我可以像上面这样的事件处理程序,它只会在第一个参数类似于ET.Dying并且第二个参数是一个回调的情况下编译DyingEvent。如果回调有一个DamageEvent参数,我希望它无法编译,如果这有意义的话。

可以做到这一点,如果可以,怎么做?

标签: typescripteventstypespublish-subscribe

解决方案


弄清楚了:

interface EventMap {
  [ET.Collision]: CollisionEvent;
  [ET.Dying]: DyingEvent;
  // etc
}

subscribe = <T extends ET>(eventType: T, callback: (scene: Scene, event: EventMap[T]) => void) => {
  this.subscriptions[eventType].push(callback);
}

// Example calling code below here:

scene.events.subscribe(ET.Dying, handleEntityDeath);

handleEntityDeath = (scene: Scene, event: DyingEvent) => {
  scene.deleteEntity(event.entity);
}

推荐阅读