Код Middle Классы и интерфейсы спрашивают часто обновлено
Типизированный EventEmitter с картой событий
Условие
Напиши класс TypedEmitter<Events extends Record<string, unknown[]>>, где Events это карта «имя события → кортеж аргументов». Методы:
on<E extends keyof Events>(event: E, fn: (...args: Events[E]) => void): () => void: подписка, возвращает функцию отписки;emit<E extends keyof Events>(event: E, ...args: Events[E]): number: синхронно вызывает слушателей, возвращает их число.
Так emit('order:paid', 'id') без суммы не скомпилируется. run(ops) в заготовке гоняет сценарий: каждая операция ['emit', id, amount] или ['off'] (отписать первого слушателя).
Примеры
run([["emit", "A1", 500]]) // ["mail A1 500", "crm A1", "listeners 2"]
run([["off"], ["emit", "B2", 10]]) // ["crm B2", "listeners 1"]
run([["emit", "C", 1], ["off"], ["off"], ["emit", "D", 2]]) // ["mail C 1", "crm C", "listeners 2", "crm D", "listeners 1"]
Как подойти
Подсказки: 2
- Хранилище слушателей: mapped-тип
{ [E in keyof Events]?: ((...args: Events[E]) => void)[] }. - Кортежи с метками (
[orderId: string, amount: number]) дают имена параметров в подсказках IDE.
Решите в тренажёре
Редактор с автотестами прямо в браузере. Можно решить спокойно, вслух или под таймером, как на собесе.