问题是您试图将(arg: keyof T) => any 分配给(arg: T[K]) => any。 keyof T 代表T 的任意属性名例如在这个类中:
class X { test: string; test2: number; }
keyof X 与'test' | 'test2' 相同
而T[K] 和K extends keyof T 表示T 名称为K 的属性类型,因此对于T[K] 上面的类,可以是number 或string,具体取决于为@ 传递的值987654335@
因此,如果您有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