Remove any from this repo and make the ban permanent.
Current state
npm test reports 105 eslint warnings, every one of them @typescript-eslint/no-explicit-any
(0 errors, so they don't fail the build today). src/AgController/index.ts carries the worst of it —
server: any, clients: any[], let r: any, receiver: { value: any; done: any }, plus a dynamic
(gigController)[func] dispatch that needs an eslint-disable for object injection.
tsc --noEmit already runs as part of npm test, so this is not about missing typechecking. It
is about any erasing the checks that already exist.
Definition of done
- Zero
any across the repo.
- The
@typescript-eslint/no-explicit-any rule promoted from warning to error, so a
reintroduced any fails the build rather than adding a 106th warning nobody reads.
The rule flip is the point. Without it this is a cleanup that silently undoes itself.
Handling the anys that resist
Not all 105 are laziness. Some exist because the libraries underneath have loose types — the
socketcluster server instance, its consumer's receiver shape — and the dynamic (gigController)[func]
dispatch is awkward because the method name is a runtime string. For those, in order of preference:
- Write local type declarations covering just the parts of the third-party shape this repo
actually touches — a small interface describing the bits used, not the whole library surface.
This is the default approach.
- Inline
eslint-disable with a mandatory comment explaining why the any is genuinely
unavoidable. This is the fallback, so that promoting the rule to error is not a trap. A disable
with no explanation is not acceptable.
Delivery
One PR for the whole sweep, including the rule flip, closing this issue.
Dispatch note
Sonnet. Because it is a single large diff with no incremental review, do the local type
declarations first and report back before touching the remaining sites — the abstraction needs to
be seen before it propagates across a hundred-odd call sites.
Not in scope
The discriminated-result design for the socket layer — returning
{ ok: true } | { ok: false, message } from the mutating gig operations instead of throwing — is a
separate concern and is deliberately not part of this issue. AgController.updateGig's current
rethrow behaviour, as shipped in PR #254 for WebJamSocketCluster#253 "Failed gig update reports
nothing: updateGig swallows its error, so neither socketError nor gigUpdated is emitted", stays
exactly as it is. Do not change error-handling behaviour while doing this cleanup.
Acceptance criteria
- No
any remains in the repo except where accompanied by an explanatory eslint-disable comment.
@typescript-eslint/no-explicit-any is configured as an error, and npm run lint passes.
- Local type declarations are used in preference to disables wherever the shape is knowable.
- No behavioural change of any kind — this is types only.
npm test green: eslint clean, tsc --noEmit clean, all vitest tests passing.
Opened 2017-09-07 with an empty body and two comments linking to Polymer HTML-import issues, from a
stack this repo no longer uses. Scope agreed and body written 2026-07-25.
Remove
anyfrom this repo and make the ban permanent.Current state
npm testreports 105 eslint warnings, every one of them@typescript-eslint/no-explicit-any(0 errors, so they don't fail the build today).
src/AgController/index.tscarries the worst of it —server: any,clients: any[],let r: any,receiver: { value: any; done: any }, plus a dynamic(gigController)[func]dispatch that needs an eslint-disable for object injection.tsc --noEmitalready runs as part ofnpm test, so this is not about missing typechecking. Itis about
anyerasing the checks that already exist.Definition of done
anyacross the repo.@typescript-eslint/no-explicit-anyrule promoted from warning to error, so areintroduced
anyfails the build rather than adding a 106th warning nobody reads.The rule flip is the point. Without it this is a cleanup that silently undoes itself.
Handling the
anys that resistNot all 105 are laziness. Some exist because the libraries underneath have loose types — the
socketcluster server instance, its consumer's
receivershape — and the dynamic(gigController)[func]dispatch is awkward because the method name is a runtime string. For those, in order of preference:
actually touches — a small interface describing the bits used, not the whole library surface.
This is the default approach.
eslint-disablewith a mandatory comment explaining why theanyis genuinelyunavoidable. This is the fallback, so that promoting the rule to error is not a trap. A disable
with no explanation is not acceptable.
Delivery
One PR for the whole sweep, including the rule flip, closing this issue.
Dispatch note
Sonnet. Because it is a single large diff with no incremental review, do the local type
declarations first and report back before touching the remaining sites — the abstraction needs to
be seen before it propagates across a hundred-odd call sites.
Not in scope
The discriminated-result design for the socket layer — returning
{ ok: true } | { ok: false, message }from the mutating gig operations instead of throwing — is aseparate concern and is deliberately not part of this issue.
AgController.updateGig's currentrethrow behaviour, as shipped in PR #254 for WebJamSocketCluster#253 "Failed gig update reports
nothing: updateGig swallows its error, so neither socketError nor gigUpdated is emitted", stays
exactly as it is. Do not change error-handling behaviour while doing this cleanup.
Acceptance criteria
anyremains in the repo except where accompanied by an explanatoryeslint-disablecomment.@typescript-eslint/no-explicit-anyis configured as an error, andnpm run lintpasses.npm testgreen: eslint clean,tsc --noEmitclean, all vitest tests passing.Opened 2017-09-07 with an empty body and two comments linking to Polymer HTML-import issues, from a
stack this repo no longer uses. Scope agreed and body written 2026-07-25.