问题是您试图分配 (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
的属性的类型,因此对于上面的类,可以是或取决于传递的值T
K
T[K]
number
string
K
因此,如果您有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