问题是您试图分配 (arg: keyof T) => any给(arg: T[K]) => any. keyof T表示此类中的任何属性名称T例如:
class X { test: string; test2: number; }
keyof X'test' | 'test2'
与while T[K]with相同,表示带有 nameK extends keyof T的属性的类型,因此对于上面的类,可以是或取决于传递的值TKT[K]numberstringK
因此,如果您有Emitter<X>,您基本上会尝试分配(arg: string | number) => any绝对(arg: 'test' | 'test2') => any不是类型安全的。
我的猜测是,您希望约束listener具有与类成员相同的属性类型的参数。为此,您应该使用限制Map<string, ((arg: T[keyof T]) => any) []>到arg任何可能的属性类型T
class EventEmitter<T> {
private events: Map<string, ((arg: T[keyof T]) => any) []>;
constructor() {
this.events = new Map<string, ((arg: T[keyof T]) => any) []>();
}
public getOrCreateEvents<K extends keyof T>(event: K, listener: (arg: T[K]) => any): ((arg: T[K]) => any) [] {
return this.events.get(event) || this.events.set(event, new Array<(arg: T[K]) => any>()).get(event);
}
}
// Test
class X { test: string; test2: number; }
var d = new EventEmitter<X>();
d.getOrCreateEvents("test2", c => console.log(c));// c is infered to string
d.getOrCreateEvents("test2", c => console.log(c)); // c is infered to number