Ste*_*r16 8 javascript events typescript
我开始深入研究泛型并有一个看起来像这样的泛型事件类
export interface Listener < T > {
(event: T): any;
}
export class EventTyped < T > {
//Array of listeners
private listeners: Listener < T > [] = [];
Attach(listener: Listener < T > ) {
this.listeners.push(listener);
}
Emit(event: T) {
this.listeners.forEach(listener => listener(event));
}
}
Run Code Online (Sandbox Code Playgroud)
我像这样创建我的事件 onPageSizeSelected = new EventType<PageSizeSelector>();
我的听众签名是这样的PageSizeSelectedHandler(event:Event,object:PageSizeSelector)
。
当我去附加这样的事件时,pageSizeSelector.onPageSizeSelected.Attach(this.PageSizeSelectedHandler.bind(this))
不会抛出错误。当处理程序像这样附加时pageSizeSelector.onPageSizeSelected.Attach(this.PageSizeSelectedHandler)
。它立即发现方法签名不正确并且参数过多。
打字稿无法正确推断方法签名的绑定是什么?如何安全地保留this
我的事件并强类型化我的事件?
不幸的是,TypeScript 在this
自动检查上下文方面做得并不好。有建议添加类似--strictThis
编译器选项的内容,以防止您传递错误绑定的函数,但尚未实现,显然是因为它会破坏大量现有代码并对编译器性能产生重大影响。如果你想看到实现,你可能想要去那个 GitHub 问题并给出一个和/或描述你的用例(如果它特别引人注目并且尚未在该问题中提到)。
如果您真的想让编译器执行此检查,这是可能的,但是您需要手动将this
参数添加到代码中的各种位置。例如(这里有一个最小的、完整的和可验证的例子,你的定义PageSizeSelectedHandler
会派上用场),你可以做这样的事情:
// explicitly add void this-context to definition of Listener
export interface Listener<T> {
(this: void, event: T): any;
}
// explicitly add class-based this-context to all methods
class StringListeningClassThing {
myString = "hey";
doSomething(this: StringListeningClassThing, x: string) {
return x + this.myString;
}
}
const onPageSizeSelected = new EventTyped<string>();
const stringListenerThingy = new StringListeningClassThing();
// enjoy type safety
onPageSizeSelected.Attach(stringListenerThingy.doSomething); // error as desired
onPageSizeSelected.Attach(stringListenerThingy.doSomething.bind({notGood: true})); // also error
onPageSizeSelected.Attach(stringListenerThingy.doSomething.bind(stringListenerThingy)); // okay!
Run Code Online (Sandbox Code Playgroud)
所以编译器可以强制执行这些东西,但不能自动执行。不幸的是,这是我现在可以给出的最佳答案,直到并且除非--strictThis
成为一件事。
希望有帮助。祝你好运!