TGViewer
Настоящий JavaScript Настоящий JavaScript @true_js · 5.89K subscribers
Post #3588 373
⁣Строгая типизация event-сорсинга: как discriminated unions спасают от ошибок в сагах

В проектах с event-сорсингом и сагами магические строки для типов событий — частая причина production-багов. Одна опечатка в 'user_deleted' против 'user_deleted_at' — и рантайм ломает логику, которую TypeScript мог отловить на этапе компиляции. Senior-разработчики игнорируют это, пока не получают инцидент.

Discriminated unions для событий

Вместо строкового enum или raw string используй union-тип с литеральным полем type. TypeScript автоматически сужает payload в conditional-блоках:

type UserEvent =
| { type: 'USER_CREATED'; payload: { id: string; name: string } }
| { type: 'USER_DELETED'; payload: { id: string } };

function handle(event: UserEvent) {
if (event.type === 'USER_CREATED') {
// payload: { id: string; name: string } — без as
console.log(event.payload.name);
}
}


Ошибка: хардкодить строку в каждом обработчике. Используй discriminated union, чтобы компилятор проверял, что payload соответствует типу.

Type-safe саги без магии

В саге, которая агрегирует события, union-тип предотвращает обращение к несуществующим типам:

type SagaEvent =
| { type: 'ORDER_CREATED'; payload: { orderId: string } }
| { type: 'PAYMENT_CONFIRMED'; payload: { paymentId: string } };

function processSaga(events: SagaEvent[]) {
// Ошибка: 'ORDER_DELETED' не входит в union
// events.find(e => e.type === 'ORDER_DELETED');
}


Практический совет: при добавлении нового события расширяй union явно — это заставит обновить все саги, где это событие участвует. Так ты не пропустишь ветку в switch или pattern-matching.

Trade-off: размер union

При 15-20 типах union становится громоздким. Но надежность перевешивает: компилятор гарантирует, что ты не используешь несуществующий тип или payload. Альтернатива с магическими строками — это deferred runtime failure, который проявится в production.

Вывод: Discriminated unions в event-сорсинге — это не избыточность, а контракт, который делает невозможным целый класс ошибок, связанных с опечатками и несоответствием payload.
  • ❤ 1
  • 🔥 1
More from @true_js
  1. Oct 3, 2026Post #3963
  2. Oct 2, 2026😅 Айтишник отправил в одну компанию три одинаковых резюме и только одно дошло до финала О…
  3. Oct 2, 2026Post #3961
  4. Oct 2, 2026🤣 Правильно расставленные приоритеты в моей жизни би лайк: 💥 xCode Journal
  5. Oct 1, 2026🤯 Люди взбунтовались против «пыточной для ИИ» На GitHub заметили открытый проект AI Tortu…
  6. Oct 1, 2026День в Заонежье начинается ещё в дороге. Мы встретим вас в аэропорту или на вокзале. Дальш…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →