EPBDS-16211 E0: wire up TypeScript, zero behaviour change - #54
Merged
Merged
Conversation
§9.6's whole track was blocked on this: an imported .ts would not build
today, so nobody could convert even one file. No product code changes.
babel.config.js @babel/preset-typescript, listed LAST so it runs FIRST
(presets apply in reverse) and types are stripped before
preset-env and preset-react parse the file.
tsconfig.json new, checker-only. strict, noEmit, allowJs + checkJs:false
(unconverted JS resolves but is not checked, which is what
makes the migration incremental), isolatedModules,
experimentalDecorators, jsx: react.
npm run typecheck tsc --noEmit, a CI step in `verify` beside the linters.
lint:js --ext now includes .ts,.tsx.
BABEL 7, DELIBERATELY. @babel/preset-typescript@8 peer-requires
@babel/core@^8 and this project is on core 7, so the current default needs
--legacy-peer-deps. That would install a Babel-8 preset against a Babel-7
core: papering over a real mismatch, not resolving it. Pinned to ^7.
TWO THINGS THE PROBE FOUND, which is what it is for
.test.ts had no Jest globals typed, so the first TypeScript test in E1
would have broken the gate on its first day. @types/jest added, matched to
the installed major (types 30 <-> Jest 30.3.0; npm's default ^29 would have
been a major behind).
lint:js ran --ext .js,.jsx, so every .ts file would have slipped past the
zero-warning gate. The ESLint config ALREADY listed src/**/*.ts in its
overrides and eslint-config-react-app already ships @typescript-eslint —
only the CLI flag excluded them. Side effect: src/library/types/index.ts
and UIRender.tsx are linted for the first time (0 problems).
THE PROBE IS NOW A PERMANENT GUARD, not a throwaway
Item 4 asked for a probe, run and discarded. Discarding it leaves no .ts
under `include`, so the gate would be green over ZERO TypeScript — which
looks exactly like green over working TypeScript, until someone tries to
convert something. src/toolchain/typescriptSupport.ts + its test stay
instead. Both pipelines read them: tsc proves the checker sees .ts, Jest
proves Babel strips it. Verified to FAIL when the preset is removed, and to
pass when it is restored. Outside src/core and src/library, so outside
collectCoverageFrom; imported by nothing, and confirmed absent from
dist/index.js. Delete it once real converted modules cover the same ground.
MEASURED
typecheck 1.6 s over 375 source files (329 .js, 11 .jsx, 35 .json).
Non-vacuous: a mistyped file makes it exit non-zero.
suite 166 -> 167 suites, 2527 -> 2529 tests — exactly the guard.
coverage 97.04 / 94.06 / 96.88 / 97.76, unchanged; thresholds green.
CSS static/all.css sha256 unchanged, dcdb0a40a6d8ee79...
pipelines the throwaway probe, wired into src/library/index.js, passed
typecheck, Jest, build-lib and the demo build, and its output
string was found in dist/index.js — TypeScript really compiles
into the published bundle rather than being skipped.
A correction to the plan's own text, recorded there: E0 said "all four
pipelines". There are three — library build, demo build, Jest. watch-lib
stopped being a fourth when webpack.watch.config.mjs was deleted under H7.
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.
§9.6's whole track was blocked on this: an imported
.tswould not build today, so nobody could convert even one file. No product code changes.babel.config.js@babel/preset-typescript, listed last so it runs first — presets apply in reverse, and types must be stripped beforepreset-env/preset-reactparse the filetsconfig.jsonstrict,noEmit,allowJs+checkJs: false,isolatedModules,experimentalDecorators,jsx: reactnpm run typechecktsc --noEmit, a CI step inverifybeside the linterslint:js--extnow includes.ts,.tsxcheckJs: falseis what makes the migration incremental: unconverted JS resolves but is not checked, so a.tsfile may import any of the ~330.jsfiles without demanding they be converted first — while every converted file is strict from its first day.Babel 7, deliberately
@babel/preset-typescript@8peer-requires@babel/core@^8and this project is on core 7, so the current default install fails withERESOLVE. Pinned to^7rather than reaching for--legacy-peer-deps— that flag would install a Babel-8 preset against a Babel-7 core, papering over a real mismatch instead of resolving it.Two things the probe found, which is what it is for
.test.tshad no Jest globals typed. The first TypeScript test in E1 would have broken the gate on day one.@types/jestadded, matched to the installed major — types 30 ↔ Jest 30.3.0; npm's default^29would have been a major behind.lint:jsran--ext .js,.jsx, so every.tsfile would have slipped past the zero-warning gate. The ESLint config already listedsrc/**/*.tsin its overrides andeslint-config-react-appalready ships@typescript-eslint— only the CLI flag excluded them. Side effect:src/library/types/index.tsandUIRender.tsxare linted for the first time (0 problems).The probe is now a permanent guard
Item 4 asked for a probe, run and discarded. Discarding it leaves no
.tsunderinclude— so the gate would be green over zero TypeScript, which looks exactly like green over working TypeScript, right up until someone tries to convert something.src/toolchain/typescriptSupport.ts+ its test stay instead. Both pipelines read them:tscproves the checker sees.ts, Jest proves Babel strips it. Verified to fail when the preset is removed, and to pass when restored. It sits outsidesrc/core/src/libraryso it is outsidecollectCoverageFrom, nothing imports it, and it is confirmed absent fromdist/index.js. Its own comment says to delete it once real converted modules cover the same ground.This is the one place I went beyond the letter of E0 — say the word and I will drop it back to a throwaway.
Measured
.js, 11.jsx, 35.json)static/all.csssha256 unchanged,dcdb0a40a6d8ee79…The throwaway probe, wired into
src/library/index.js, passed typecheck, Jest,build-liband the demo build — and its output string was found indist/index.js, proving TypeScript really compiles into the published bundle rather than being silently skipped.A correction to the plan's own text
E0 said "all four pipelines". There are three — library build, demo build, Jest.
watch-libstopped being a fourth whenwebpack.watch.config.mjswas deleted under H7. Recorded in the plan.Next gate is the plan's own: go/no-go after E1, on measured conversion velocity, before committing to the E2/E3 tail.
🤖 Generated with Claude Code