Код Middle Объединения и сужение обновлено

Обработка вебхуков: union событий и in-сужение

Условие

Платёжный провайдер присылает события. Опиши union Webhook по полю event:

  • payment.succeeded: { paymentId, amount, currency: 'RUB' | 'USD' };
  • payment.canceled: { paymentId, reason };
  • refund.succeeded: { refundId, paymentId, amount }.

Напиши summarize(events): возвращает { received: Record<'RUB' | 'USD', number>; refunded: number; canceled: string[] } (суммы оплат по валютам, сумма возвратов, id отменённых платежей по порядку). Неизвестные события (тип event не из списка) пропускай: данные пришли извне, поэтому вход unknown[], и каждое событие нужно проверить guard-функцией isWebhook.

Примеры

summarize([{"event":"payment.succeeded","paymentId":"p1","amount":1000,"currency":"RUB"}, {"event":"refund.succeeded","refundId":"r1","paymentId":"p1","amount":300}, {"event":"payment.canceled","paymentId":"p2","reason":"expired"}]) // {"received":{"RUB":1000,"USD":0},"refunded":300,"canceled":["p2"]}
summarize([{"event":"payment.waiting_for_capture","paymentId":"p3"}, null, "x", {"event":"payment.succeeded","paymentId":"p4","amount":5,"currency":"USD"}]) // {"received":{"RUB":0,"USD":5},"refunded":0,"canceled":[]}
summarize([{"event":"payment.succeeded","paymentId":"p5","amount":"100","currency":"RUB"}]) // {"received":{"RUB":0,"USD":0},"refunded":0,"canceled":[]}

Как подойти

Подсказки: 2
  1. Проверка "event" in v после typeof v === "object" сужает v до объекта с полем event.
  2. Внутри guard удобно один раз привести к Record<string, unknown> и проверить поля по варианту.

Решите в тренажёре

Редактор с автотестами прямо в браузере. Можно решить спокойно, вслух или под таймером, как на собесе.