我正在构建一个小型事件处理类,并且遇到了打字问题,我无法完成工作。考虑以下几点:可以分别键入函数参数吗?
export interface IEventListener<A> {
(...A): boolean | void;
}
export default class EventDispatcher<A> {
private listeners: IEventListener<A>[] = [];
constructor(...listeners: IEventListener<A>[]) {
listeners.forEach((listener) => {
this.addListener(listener);
});
}
public addListener(listener: IEventListener<A>): void {
if (this.listeners.indexOf(listener) === -1) {
this.listeners.push(listener);
}
}
public removeListener(listener: IEventListener<A>): void {
const index = this.listeners.indexOf(listener);
if (index !== -1) {
this.listeners.splice(index, 1);
}
}
public triggerListeners(...A): boolean {
const args = arguments;
return this.listeners.every((listener) => {
return listener(args) === false;
});
}
}
(你必须原谅捏造的语法)
这里,泛型类型A
代表在参数的签名,无论是在传递到听众使用的功能调度员,并在调度员的triggerListeners
功能。
我真的希望能够做的,是宣布一个新的EventDispatcher
用强类型参数的接口,像这样:
const ed = new EventDispatcher<(name: string, street: string)>();
,或者更理想的是,利用推理:
const ed = new EventDispatcher((name: string, street: string) => {
console.log(name, street);
});
使得:
ed.triggerListeners("Sandy", "100th"); // no error
ed.triggerListeners("Sandy", 100); // error
是否可以键入函数的参数分别为并将它们作为泛型类型传递?
目前,我知道了设置,使听众只能接受单一类型的对象:
export interface IEventListener<T> {
(T): boolean | void;
}
const ed = new EventDispatcher<{name: string, street: string}>();
这是很好的,我猜,但缺乏一定的打字稿-Y技巧。
我认为这可能是一样好。它确实能够满足我的需求,尽管不幸的是更广泛的问题以“不”的方式回答。 –