Skip to content

Comments

refactor: replace @ts-expect-error with typed assertions in hook system#24

Open
glacierphonk wants to merge 1 commit intogramiojs:mainfrom
glacierphonk:refactor/bot-hook-types
Open

refactor: replace @ts-expect-error with typed assertions in hook system#24
glacierphonk wants to merge 1 commit intogramiojs:mainfrom
glacierphonk:refactor/bot-hook-types

Conversation

@glacierphonk
Copy link
Contributor

Summary

Removes 15 @ts-expect-error suppressions and 7 TODO comments from the hook system in src/bot.ts by replacing them with targeted type assertions.

Changes by area

runImmutableHooks (was: //TODO: solve that later)

  • Cast the hooks array to a function type matching the correlated context parameters. This is a correlated union that TypeScript can't narrow automatically — the type parameter guarantees the hook and args match at runtime.

Hook registration methods (preRequest, onResponse, onResponseError, onApiCall)

  • methods.includes(context.method): Cast methods to readonly string[] so .includes() accepts the wider keyof APIMethods value. The runtime guard ensures only matching methods reach the handler.
  • handler(context): Cast context to the handler's narrowed parameter type (e.g., Hooks.PreRequestContext<Methods>). Safe because the .includes() guard above guarantees the method matches.
  • Wrapper function: Cast the entire wrapper to the store's hook type (e.g., as Hooks.PreRequest). The wrapper accepts the wide type and delegates to the narrow handler when matched.
  • Else branch (direct push): Cast methodsOrHandler to the store type. TypeScript can't fully narrow the generic union through typeof/Array.isArray guards, but the overload signatures guarantee this is the function type.

_callApi onResponse hook call (was: // TODO: fix type error)

  • Cast the response object to Parameters<Hooks.OnResponse>[0]. Also removed the as any cast on data.result that was previously needed.

onError handler (was: // TODO: Sorry... fix later)

  • Cast errContext to the handler's expected parameter type after the .is() runtime guard narrows the context.

onResponseError wrapper — also forwards the api parameter to the filtered handler (it was silently dropped in the original wrapper).

Why casts over @ts-expect-error

@ts-expect-error suppresses the entire next line, masking any future unrelated type errors. Explicit as casts only affect the specific expression and document exactly which type boundary is being crossed. They also produce better IDE hover information.

Test plan

  • bun test — all 208 tests pass
  • bun run type — clean (tsc --noEmit)
  • bun run lint — no new warnings (all warnings are pre-existing in other files)

Remove 15 @ts-expect-error suppressions and 7 TODO comments from the
hook system by using targeted type assertions:

- runImmutableHooks: cast hooks array to match correlated context
  params, resolving the "solve that later" TODO
- preRequest/onResponse/onResponseError/onApiCall registration:
  cast methods array to readonly string[] for .includes() checks,
  cast context to the narrowed handler type, and cast wrapper
  functions to their store types
- _callApi onResponse: cast the response object to the hook's
  expected parameter type, also removing the as-any on data.result
- onError: cast errContext after the .is() runtime guard

Each cast is sound because the runtime logic (method filtering,
.is() narrowing, type parameter correlation) guarantees the types
match. Explicit casts are preferable to @ts-expect-error because
they only suppress the specific expression and won't mask future
unrelated type errors on the same line.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant