需要在 Typescript 接口中处理事件

Require Handling of Event in Typescript Interface

给定以下 class + 接口:

class Sprite implements Renderable{
    constructor(){
        this.on("pointerdown", this.onClick)
    }
    onClick(){
        console.log("clicked!")
    }

}

interface Renderable{
    // what goes here?
}

如何在我的接口中创建一个要求,使该接口的所有实现都必须处理“pointerdown”事件?

打字稿中有这个吗?

您可以为处理程序指定接口,然后始终使用它来附加处理程序,但不能为事件发射器本身指定接口。要么让它成为一个接口契约(即文档,而不是类型检查),要么将它们分成两部分,这样实现就不需要自己安装处理程序:

class Sprite extends Renderable {
    onClick() {
        console.log("clicked!")
    }
}

abstract class Renderable {
    constructor() {
        this.on("pointerdown", this.onClick)
    }
    abstract onClick(): void;
}

您如何为此定义类型取决于您在能够访问回调中的事件变量方面所需的特异性级别。如果您根本不想通过该事件,那么显然这是最简单的方法。您可以使用像 Event 这样的模糊类型定义来访问所有事件中存在的属性,但这会错过某些仅存在于特定事件接口中的属性,例如 MouseEventTouchEvent, 等等。你提到你只想处理类型为 PointerEvent.

"pointerdown"

如果您想访问 e.target,那么您将侦听器附加到哪种类型的元素也很重要。

DOM 类型中内置了针对不同对象和元素的各种事件映射,例如 WindowEventMap,还有一个通用的 GlobalEventHandlersEventMap.

这个版本的接口是最通用的:

interface Bindable1 {
  on( type: string, listener: (e: Event) => void ): void;
}

这将根据名称推断出正确的事件类型:

interface Bindable2 {
  on<K extends keyof GlobalEventHandlersEventMap>( type: K, listener: (e: GlobalEventHandlersEventMap[K]) => void ): void;
}

这是最灵活的,因为它允许您指定特定的事件映射,例如 FileReaderEventMapAnimationEventMap 等,这可能会添加其他特定事件。但是我们默认设置为GlobalEventHandlersEventMap,这样你不想指定就不用指定了。

interface Bindable3<Map = GlobalEventHandlersEventMap> {
  on<K extends keyof Map>( type: K, listener: (e: Map[K]) => void ): void;
}

How can I create a requirement within my interface such that all implementations of this interface must handle the event of "pointerdown"?

我不是 100% 清楚你的要求是什么。您是否希望您的界面包含一个事件处理程序 (onClick),然后您可以将其附加到“pointerdown”事件?还是您希望他们专门声明对“pointerdown”的处理?

我已经解释了你如何定义 this.on,但我也不清楚你在哪里实现 this.on.

这是一个可能有效的简单设置。我们为任何具有 属性 onClick.

的对象定义一个 interface
interface HasClickHandler {
    onClick(e: MouseEvent): void;
}

您可以选择在何处附加 onClick 回调。在这里,我将其附加到 window。我正在使用 (e) => obj.onClick(e) 而不是 obj.onClick 以便回调的 this 上下文是对象而不是 window.

function handlePointerDown( obj: HasClickHandler ) {
    window.addEventListener( "pointerdown", (e) => obj.onClick(e) ); 
}

这个 class 实现了 HasClickHandler 接口,所以它可以调用 handlePointerDownthis 作为参数。

class Sprite implements HasClickHandler {
    constructor() {
        handlePointerDown(this);
    }
    onClick() {
        console.log("clicked!");
    }
}