chore(deps): bump typescript-eslint 8.19.0 → 8.66.0 (#86 sweep, step 1) - #171
Merged
Merged
Conversation
Step 1 of the eight-step frontend toolchain sweep in docs/upgrades/frontend-toolchain-86.md, taken alone because it is the only unblocking move in that sequence. The pinned 8.19.0 capped typescript at <5.8.0 and eslint at ^9; 8.66.0 raises those to <6.1.0 and ^10.0.0, which is what steps 2 (ESLint 10) and 4 (TypeScript 6.0.3) are gated behind. Only typescript-eslint moves. No ESLint or TypeScript config was edited, typescript stays at 5.7.2 and eslint at 9.39.4, and no later sweep step is touched. Two of the scoping document's predictions did not hold: - An existing rule's implementation got stricter. The rule set is unchanged as predicted (recommended-type-checked.js is identical across the span, 50 entries either side), but no-unnecessary-type-assertion now catches what it previously missed and reported two redundant `'' as string` assertions in NewScanPage.tsx. Removed by hand at those two sites only; tsc -b confirms the inferred useForm type is unchanged and the emitted bundle keeps the same content hashes. "No new rules" does not mean "no new findings." - The effective rule set did change. The document's byte-for-byte claim diffed one of the three files recommendedTypeChecked composes; the layer it did not diff gains `no-with: 'off'`, dropping that rule from error to off in the resolved config. Accepted rather than restored: `with` is a hard compile error under this repo's tsconfigs, verified at the compiler (TS1101 plus TS2410) rather than argued from the strict flag. Lockfile movement is confined to the typescript-eslint subtree, 374 -> 362 packages, with each of the 17 removals checked to have no surviving requirer. Written with npm 11.19.0 to match CI's Node 24. Suites unchanged against a re-measured pre-bump baseline: lint clean, Prettier clean, 79 tests across 21 files, 7035 modules to 645.18 kB JS / 201.38 kB CSS, npm audit 0 at every severity. See docs/ARCHIVE.md section 14 for the full record.
tyler-rich
added a commit
that referenced
this pull request
Aug 9, 2026
…r 8 (#189) Three Track A edits in docs/ROADMAP.md, each gated on a live check made this session rather than on a prior session's claim: - Strike the "Frontend tooling majors from Dependabot #86" item as Done 2026-08-09, naming all eight sweep PRs (#171, #174, #177, #179, #180, #183, #185, #187) and both deliberately-excluded packages (TypeScript 7 and @types/node 26). All eight squash commits re-confirmed present on dev before writing the bullet. - Strike the GHSA-qwww-vcr4-c8h2 re-cut request: the advisory has already been re-cut upstream to >= 7.12.0, < 7.18.2 plus >= 8.0.0, < 8.3.0, with the 8.x range untouched. Verified against the record in github/advisory-database and independently against the npm registry's advisory endpoint, which returns nothing for 7.18.2. - Reword react-router 7 -> 8 as blocked on a React 19 decision rather than on a tooling bump, and move it out of the tooling-majors grouping into Longer-term / speculative. react-router@8.3.0 peers react and react-dom at >=19.2.7; this repo pins both at 18.3.1. See docs/ARCHIVE.md section 14 for the dated record of what was verified for each.
tyler-rich
added a commit
that referenced
this pull request
Aug 9, 2026
…a current reason (#193) Comment-only change to the npm /frontend entry. No ignore rule, group, schedule, target-branch or any other key is added, removed or modified. The paragraph's instruction — leave the frontend tooling majors unignored so Dependabot keeps surfacing them — is still correct. Its stated reason was not: it called them "the deferred #86 sweep" and said to surface them "until that PR is done". The sweep completed 2026-08-09 across #171, #174, #177, #179, #180, #183, #185 and #187, and docs/ROADMAP.md marks the item Done (verified before writing). So the comment had begun arguing against its own instruction — a reader who checked the roadmap would find the work finished and reasonably conclude the exemption had expired, whose obvious next move is to add the typescript ignore, which is the one thing that must not happen. Rewritten so the instruction rests on two current reasons. The tooling majors stay unignored as ordinary policy: we want to see them, evaluate them and land them, which is exactly what the sweep did (pointing at docs/upgrades/frontend-toolchain-86.md rather than restating it). typescript stays unignored for a sharper reason: TypeScript 7 is wanted, the blocker is entirely upstream, and the regenerating Dependabot PR proposing 7.x IS the notification that tells us when typescript-eslint ships support — an ignore would suppress the signal while changing nothing about the blocker. The re-check command is inlined so the next reader can test it without a session, along with the expected shape of support (a new typescript-eslint MAJOR built against TS 7's ./unstable/* API, not a point-release range widen). Verified by parsing rather than by reading: both versions load with yaml.safe_load to byte-identical canonical JSON (SHA-256 07e71c6c on each side), and every changed raw line matches ^[+-]\s*#.
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.
Step 1 of the eight-step sequence in
docs/upgrades/frontend-toolchain-86.md, taken alone because it is the only unblocking move in the set. The pinned 8.19.0 cappedtypescriptat<5.8.0andeslintat^9; 8.66.0 raises those to<6.1.0and^10.0.0, which is what steps 2 (ESLint 10) and 4 (TypeScript 6.0.3) are gated behind.Scope held exactly: only
typescript-eslintmoves. No ESLint or TypeScript config was edited,typescriptstays at 5.7.2 andeslintat 9.39.4, no later sweep step is touched, and#153remains open and unactioned.Target re-checked against the registry rather than taken from the document:
latestis still 8.66.0, with only8.66.1-alpha.*canaries beyond it. The §3.1 one-liner also still returnstypescript: >=4.8.4 <6.1.0, so the TypeScript 6.0.3 ceiling holds as of today.Both are recorded in
docs/ARCHIVE.md§14, and both matter for the remaining steps.1. An existing rule's implementation got stricter
The prediction that the rule set is unchanged is correct and was confirmed at the artifact: 8.19.0's
dist/configs/recommended-type-checked.jsand 8.66.0'sdist/configs/flat/recommended-type-checked.jsare identical — 50 entries either side, 43@typescript-eslint/*rules plus 7 core disables, same severities, same options.But an unchanged rule set does not imply an unchanged set of reports. Across 47 minors
@typescript-eslint/no-unnecessary-type-assertionlearned to catch a case it previously missed, and fired twice on code that has been in the tree unchanged:@typescript-eslint/no-unnecessary-type-assertionNewScanPage.tsx:139registryId: '' as stringNewScanPage.tsx:140gitCredentialId: '' as stringBoth assertions were genuinely redundant (
''already widens tostringas a mutable object-literal property) and both were removed by hand at those two sites only — no--fix, no bulk autofix.tsc -bpasses afterwards, confirminguseForm's inferredinitialValuestype is unchanged, and the emitted bundle keeps the same content hashes (index-BNB6IweX.js,index-D2wHtcHV.css), which is the proof a type-only assertion erases to identical JavaScript.The transferable rule: "no new rules" does not mean "no new findings." §0.3's headline — "The typescript-eslint bump does not change which rules run" — reads as a reassurance about outcomes and gets cited as one. Step 1's own row is more careful ("only detection improves", priced S–M / 1–3 h "dominated by however many reports appear"), so the budget was right; the headline is what misleads. Steps 2 and 4 both cross far more implementation change than config change.
2. The effective rule set did change — the claim is wrong, not just incomplete
§0.3 states the shipped
recommendedTypeCheckedis "byte-for-byte identical… nothing added, removed, or re-severitied." The cause of the error is scope:tseslint.configs.recommendedTypeCheckedis a three-layer composite (base+eslint-recommended+recommended-type-checked), and the document diffed only the third file, then generalised to the whole composite.dist/configs/…/recommended-type-checked.js(diffed by the doc)dist/configs/eslint-recommended-raw.js(not diffed by the doc)+ no-with: 'off'Because
eslint.config.jsextendsjs.configs.recommendedbefore the tseslint layers,eslint --print-configshowsno-withgoing fromerror([2]) tooff([0]) across all three file classes — app.tsx, library.ts, and the test override. The only other resolved-config difference is the parser identity string, which is expected.Accepted rather than restored, with the premise verified rather than argued. The "
withis already a compile error" case only holds under strict mode, and a non-module.tsfile is not strict by default. Both tsconfigs set"strict": trueand"moduleDetection": "force"— and rather than stop at the flags, a probe file containing awithstatement was compiled:tsc -breturnsTS1101: 'with' statements are not allowed in strict modeplusTS2410. Probe deleted.no-withwas not re-added toeslint.config.js; one line in therulesblock restores it if that judgement is revisited.Standing consequence for the rest of the sweep
The document's evidence discipline is genuinely good — every claim cited to a published peer range or an upstream guide, eleven tarballs unpacked to check artifacts directly. The failure here was not sloppiness but scope: one file diffed, conclusion stated about a composite of three. Steps 2, 3 and 4 rest on comparable single-artifact reads (the 14 React Compiler rules from
eslint-plugin-react-hooks@7.1.1's bundle, the three neweslint:recommendedrules from@eslint/js@10.0.1, the TypeScript 6.0 option audit). Each should be re-verified against the installed tree when its step runs, not trusted.Lockfile — everything that moved
package.jsonchanged one line. The lockfile went 374 → 362 packages; every movement is inside thetypescript-eslintsubtree or orphaned by it, attributed by parsing both lockfiles and resolving each removed package's requirers.@typescript-eslint/*packages 8.19.0 → 8.66.0, plusts-api-utils1.4.3 → 2.5.0 and, nested undertypescript-estree,minimatch9.0.9 → 10.2.6 andbrace-expansion2.1.4 → 5.0.9.@typescript-eslint/project-serviceand@typescript-eslint/tsconfig-utils(new first-party splits oftypescript-estree), plus three nested copies that exist only because the top-level ones stay pinned for ESLint 9:ignore@7.0.6,eslint-visitor-keys@5.0.1,balanced-match@4.0.4.typescript-estreeswappedfast-globfortinyglobby, which was already in the tree at 0.2.17 and satisfies its^0.2.15, so nothing new landed. Droppingfast-globorphaned its whole subtree:@nodelib/fs.{walk,scandir,stat},fastq→reusify,run-parallel→queue-microtask,merge2,micromatch→braces→fill-range→to-regex-range→is-number, the top-levelpicomatch@2.3.2, and the nestedfast-glob/node_modules/glob-parent@5.1.2.graphemerwent with theeslint-plugin. Each was checked to have no surviving requirer —eslint's own top-levelglob-parent@6.0.2and vite/vitest's nestedpicomatch@4.xare untouched.lockfileVersionstays 3 with no normalization churn, because the lockfile was written with npm 11.19.0 in a scratch prefix to match CI's Node 24 rather than the sandbox's npm 10.9.7 — the method recorded in the 2026-08-09 lockfile-refresh entry. Worth repeating: a 486-line diff from a real dependency change is hard to audit with a whole-file re-normalization mixed in.Verification
The pre-bump baseline was re-measured on 8.19.0 rather than quoted, and reproduced the document's §1 exactly. After the bump and the two-line fix, from a fresh
rm -rf node_modules && npm ci:npm run lintnpm run format:checknpm testnpm run buildnpm auditpackage-lock.json's SHA is stable acrossnpm ci.See
docs/ARCHIVE.md§ Deviations for the full record of what changed in this step.