以下是我解决您问题的方法,并指出我必须清理很多东西并猜测您在做什么:
interface MyFunctions {
FIRST_FUNCTION: () => void;
SECOND_FUNCTION: (x: string, y: number) => void; // FIXED
}
// constrain Functions to a type holding only function properties
class Params<Functions extends Record<keyof Functions, (...args: any[]) => any>> {
private functions: Map<keyof Functions, Set<Functions[keyof Functions]>> = new Map();
// use Parameters as requested
public boom<K extends keyof Functions>(func: K, ...args: Parameters<Functions[K]>) {
// assert that it returns a set of the right kind of function
const funcSet = (this.functions.get(func) || new Set()) as Set<Functions[K]>;
// okay, and remember to use spread
funcSet.forEach(f => f(...args));
}
}
new Params<{a: string}>(); // error, string is not a function
new Params<MyFunctions>().boom("FIRST_FUNCTION"); // okay
new Params<MyFunctions>().boom("SECOND_FUNCTION", "a", 1); // okay
与您的问题有关的部分:
我将泛型类型限制为,以便编译器知道的所有属性都必须是函数。这将阻止您调用.Functions
Record<keyof Functions, (...args: any[]) => any>
Functions
new Params<{a: string}>()
我已将args
其余参数键入为Parameters<Functions[K]>
,其中使用键Functions[K]
查找的属性。由于由于泛型约束,编译器知道它必须是函数类型,因此很高兴允许您将其传递给并返回参数的元组。Functions
K
Functions[K]
Parameters<>
我重新编写了实现,boom()
以使我更有意义。我需要做一个类型断言来让编译器相信产生的this.functions.get(func)
实际上是一组而Functions[typeof func]
不是一组更宽的Functions[keyof Functions]
. 并且我调用了获取的每个函数元素,在参数上Set
使用扩展语法。如果这些假设是错误的,希望它们仍能引导您朝着有用的方向前进。
希望有帮助;祝你好运!