У меня есть такой код, метод с двумя перегрузками:
/**
* Returns all keys of object that have specific value:
* @example
* KeysOfType<{a:1, b:2, c:1}, 1> == 'a' | 'c'
*/
type KeysOfType<MapT extends Record<string, any>, ValT> = {
[K in keyof MapT]: MapT[K] extends ValT ? K : never;
}[keyof MapT];
export class Hooks<EventsMap extends Record<string, any>> {
fireHooks<K extends KeysOfType<EventsMap, void>>(
event: K,
context: void,
): Promise<void>;
fireHooks<K extends keyof EventsMap>(
event: K,
context: EventsMap[K],
): Promise<void>;
fireHooks<K extends keyof EventsMap>(event: K, context: EventsMap[K]) {
// ...
}
}
Предполагается, что он будет использоваться вот так:
type MyHooks = {
aaa: void;
bbb: { data: string }
};
let h = new Hooks<MyHooks>();
h.fireHooks('aaa');
h.fireHooks('bbb', { data: 'data' });
Есть общий c класс Hooks
с методом fireHooks
, который использует сопоставление имени события и данных контекста для проверки контекста события. Некоторые события можно вызывать без какого-либо контекста, поэтому я хочу, чтобы этот метод вызывал эти события только с одним аргументом.
Все работает нормально, но проблема в том, что эти перегрузки выглядят некрасиво и излишне.
Если я пропускаю перегрузки, TS жалуется на h.fireHooks('aaa');
с
Expected 2 arguments, but got 1.ts(2554)
Если я пропускаю только вторую перегрузку, которая кажется 100% копией реализации, TS жалуется на h.fireHooks('bbb', { data: 'data' });
с
Argument of type '"bbb"' is not assignable to parameter of type '"aaa"'.ts(2345)
Может кто-нибудь объяснить
- почему мне нужна 1-я перегрузка, чтобы можно было пропустить параметр
- и почему мне нужна 2-я перегрузка, которая кажется избыточный, поскольку он полностью совпадает с реализацией?