Вот как я решу вашу проблему, отметив, что мне пришлось убирать много вещей и делать предположения о том, что вы делаете:
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
Детали, относящиеся к вашему вопросу:
I ограничено универсальный тип 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
, используя расширенный синтаксис для аргументов.Если эти предположения неверны, мы надеемся, что они по-прежнему направят вас в полезном направлении.
Надеюсь, это поможет;удачи!