Uh oh!
There was an error while loading. Please reload this page.
test(i18n): type-check its tests and clear its TEST_DEBT entry (#4040) - #4317
Merged
Conversation
Tranche 2, package 3 of 3. `tsconfig.test.json` per the #3032 template, chained from `type-check`; TEST_DEBT declared 13, measured 103 at this branch point (main moved a long way since that sweep), now 0. Two shapes account for all of them: - 90x TS7053 — `Object.keys(builtInLocales)` erases which keys it enumerated, so `builtInLocales[lang]` was an implicit-`any` index into a `const` map and the parity suites were comparing packs the compiler never confirmed exist. Derived from the map (`keyof typeof builtInLocales`), the convention three sibling files in this directory already used. - 12x TS2769 — every `React.createElement(I18nProvider, {…}, children)` wrapper. `children` is a required prop and createElement's overloads check the props object alone, so the variadic form never satisfied them. Moved into props; identical at runtime. Plus one TS2537 on an optional indexed-access cast. Case count unchanged either side: 38 files, 662 tests, before and after. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Qqyix2QcnpUC9XeYVDzx3
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
yinlianghui
marked this pull request as ready for review
August 11, 2026 13:58
github-merge-queueBot
removed this pull request from the merge queue due to a conflict with the base branch
Aug 11, 2026
…vals kept, this PR's removal kept)
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
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 freeto 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.
Part of #4040 — tranche 2, package 3 of 3. One package per PR, per the 裁决 on objectstack-ai/objectstack#4118 (PM, 2026-08-03): 小包先行,
core(80)/react(76) 最后; 每包独立 PR; 守卫类 PR 必须附 pre-fix 代码报红的运行记录; TEST_DEBT 条目随包清零, 只减不增.TEST_DEBTTS2769x9421c145af), template as-isTranche 1 found the registry two tranches stale for
plugin-grid(declared 2, measured 4) and the batch was told to re-measure rather than trust it. Here the drift is an order of magnitude:mainhas moved a long way since the original sweep and this package's test tree grew with it — 38 test files now, and the wholeobjectui#3546namespace family (auth / console / organization / perm-home / marketplace-preview / residue) landed after the number was taken. The 12TS2769are recognisably the declaredTS2769x9; everything else is new tree.The PM should know this before sizing tranche 3: on the registry's numbers i18n was the fifth-smallest debt; on measurement it is the third-largest after
coreandapp-shell, and larger thancomponents(31). Nothing in the registry's other entries has been re-measured by this PR, so the same drift may be sitting under any of them.A measurement trap worth recording, because it nearly produced a false number
The first measurement run reported 21 errors, and it was wrong — the run was piped through
tee … | head -40for display,headexited after 40 lines, andtsctook theSIGPIPEand stopped mid-output. Twenty-oneTS7053errors print exactly 42 lines, so the truncation landed on a plausible-looking boundary and would have read as a complete result. Re-run without the pipe, the same tree reports 103. Any measurement command in this card should write to a file and count afterwards, neverheada compiler mid-stream.The 90 x TS7053: the parity suites were indexing a map the compiler never checked
builtInLocalesis{ en, zh, ja, ko, de, fr, es, pt, ru, ar } as const, butObject.keyserases which keys it enumerated, sobuiltInLocales[lang]with a plainstringis an implicit-anyindex. Every locale-parity, namespace-backfill and residue suite in the package was written that way — so each was comparing packs the compiler never confirmed exist, and a mistyped locale code would have yieldedundefinedand been asserted against rather than failing.The repair is derivation from the map, not a new enumeration:
which is the convention three files in this very directory already used —
authRemediation-locale-parity.test.ts,cloudConnection-locale-parity.test.tsandinboxBadgeBreakdown-i18n-7233.test.ts. It spreads to the smaller variants of the same shape:it.each(['en', 'zh'])gainsas constso the two literals stay literals,Object.keys(NATIVE_SCRIPT)is asserted back toLocaleCode[]withNATIVE_SCRIPTre-keyed asPartial< Record< LocaleCode, RegExp > >, and the hand-written tables (ANCHORS,UNIT,EXPECTED) get their locale column typed. A locale added to or removed frombuiltInLocalesnow reaches these suites for free.The 12 x TS2769: every provider wrapper in the package
I18nProviderProps.childrenis required, and React'screateElementoverloads check the props object alone — the variadic third argument never satisfies a requiredchildren.childrenmoves into the props object at all twelve sites. Identical at runtime; React merges variadic children into props itself.Plus one TS2537
spec-translations.test.tscast a fixture throughSpecTranslationData['objects'][string], butobjectsis optional, so the indexed access isRecord< … > | undefined— which has no index signature.NonNullable< SpecTranslationData['objects'] >[string]names the record the fixture is one entry of.No public type was touched and none looks wrong.
builtInLocalesbeing aconstmap is exactly right; the tests were simply throwing that away.Discrimination proof — three probes, all reverted, none in the diff
1. The new test project can fail (the #3009 third failure mode: a
tsconfig.test.jsonthat exists but nothing runs). A provably-false line appended toi18n.test.ts:2. The derivation is what makes it compile. Reverting only the
as LocaleCode[]onall-locales-key-parity.test.tsbrings the exact pre-fix errors back, at all three of that file's sites:3. The derivation checks locale names, which is the part that is actually new. Adding a pack that does not exist to a pinned list —
it.each(['en', 'zh', 'zh-Hant'] as const)inraw-key-call-sites-3546.test.tsx:Before this PR that line compiled and the case ran against
undefined. That is the failure mode the whole card exists to remove: a green test asserting something the compiler was never allowed to look at.4. Twenty-one files' parametrised lists were re-typed, so the case matrix is asserted, not assumed. The count is the assertion here — a mis-typed
as constor a narrowedit.eachlist would silently run fewer cases while every type check stayed green. Measured on the branch point and on the branch, same command:Not one case gained or lost. (The revert/restore was done with a patch file inside this worktree — never
git stash, whose stack is shared across worktrees.)Verification
No consumer sweep is reported, and that is not an omission: nothing outside
src/__tests__/changed apart from thetype-checkscript and the new project file, so there is no exported type for a downstream package to be checked against.This package had no
tsconfig.typetests.jsonto supersede, and itstype-checkwas a baretsc --noEmit; the test project is simply chained onto it.TEST_DEBTshrinks by exactly this package's line; no other entry is touched.Changeset
Empty frontmatter —
check-changeset-presence.mjsarbitrated it, and it is a pass rather than a workaround: only test sources changed, so this releases nothing.Generated by Claude Code