我开始深入研究泛型,并拥有一个看起来像这样的泛型事件类
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));
}
}
我像这样onPageSizeSelected = new EventType<PageSizeSelector>();
我的听众签名是这个PageSizeSelectedHandler(event:Event,object:PageSizeSelector)
。
当我附加这样的事件pageSizeSelector.onPageSizeSelected.Attach(this.PageSizeSelectedHandler.bind(this))
时,不会引发任何错误。
当像这样pageSizeSelector.onPageSizeSelected.Attach(this.PageSizeSelectedHandler)
附加处理程序时。它立即发现方法签名不正确并且参数太多。
做什么的打字稿不能正确地推断方法签名?如何安全地保存我的this
并强行输入我的活动?
答案 0 :(得分:2)
不幸的是,TypeScript在自动检查this
上下文的类型方面做得不好。有suggestion添加了类似--strictThis
的编译器选项,可以防止传递错误绑定的函数,但尚未实现,显然是因为它会both break lots of existing code and have a significant compiler performance impact 。如果您想看到已实现的实现,则可能需要转到that GitHub issue并给它一个和/或描述您的用例(如果它特别引人注目并且在该问题中未提及)。
如果您真的想让编译器进行此检查,则 是可能的,但是您需要手动将this
parameters添加到代码中的所有位置。例如(在这里定义为PageSizeSelectedHandler
的{{3}}会派上用场),您可以执行以下操作:
// 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!
因此编译器可以强制执行此操作,但不能自动执行。不幸的是,这是我目前能给出的最好的答案,直到并且除非--strictThis
成为事实。
希望有帮助。祝你好运!