refactor(types): replace 62 as-any casts with type-safe event dispatch - #140
Merged
joshuawheelock merged 3 commits intoJun 4, 2026
Merged
Conversation
Add a generic on<E>() helper that narrows BaseEvent to the specific event type at each subscription site. The single unavoidable cast (as E) is now inside the helper instead of scattered across 62 call sites in ProjectionBusFactory.
Saturate
force-pushed
the
fix/type-safe-event-bus
branch
from
June 3, 2026 17:50
9b58918 to
6360ced
Compare
This was referenced Jun 3, 2026
joshuawheelock
approved these changes
Jun 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The
ProjectionBusFactoryhad 62as anycasts, one per event subscription. Each cast silenced the compiler at the boundary between the genericBaseEventbus and the specific event types that projectors expect. If a payload field was renamed or removed, TypeScript wouldn't catch the mismatch.This PR adds a generic
on<E>()helper that concentrates the single unavoidable cast (as E) inside one function, while making every call site type-safe:The subscription also now uses the event type constants (
GoalEventType.ADDED) instead of string literals, which catches typos at compile time.Total
anycount in the codebase dropped from 203 to 141. Build passes, all 2664 tests pass.Codemod used to produce this change
The event type constant values are always the event class name (e.g.
GoalEventType.ADDED = "GoalAddedEvent"), so the codemod derives import paths and constant references from the string literal in eachbus.subscribe()call. No lookup table needed.Save as
codemod.mjsand run withnode codemod.mjs: