Repository navigation
Conversation
Every propTypes declaration is deleted: 39 blocks in 38 files, with the prop-types imports, the semantic `type` proxy (components/types.ts) and the barrel's PropTypes re-export. The host no longer forwards a class's prop types, and the form layer no longer merges them. prop-types is out of devDependencies. - The descriptions the blocks carried moved first, into the props types' JSDoc, wherever a type did not have them yet. UIRender's three undocumented props are documented in the published UIRender.UIRenderProps. - The plan's step 2, the `type` vocabulary recreated as TS aliases, is not done. Of the proxy's 41 names, the converted files used 16, and only 4 carried a meaning beyond PropTypes' own. The JSDoc carries that meaning now, and an alias of a primitive checks nothing. - Two suites allowed prop-type warnings: four entries in the examples suite, two in the nested-row suite. Measured on React 18 just before the deletion, none of the six fired. They are removed, and the nested-row suite now requires no warning at all. - prop-types is still installed as a dependency of development packages, so an import would resolve and bundle it again. no-restricted-imports now rejects it in every src override. A probe file proved that in core, in a test and in the demo. Found, and left for its own change: on React 18, the examples suite's other five allowlist entries match nothing either. Measured: the corpus is identical, with 107 / 1012 at mount, 27 / 64 on an edit and the DOM unchanged. dist/index.js went from 322,915 to 311,527 bytes, and from 107,110 to 104,047 gzipped. isRequired occurs 49 times in master's bundle and none now.
AlexSamBY
added a commit
that referenced
this pull request
Oct 1, 2026
## What changes **This finishes the TypeScript migration.** It meets every clause of the definition of done in `docs/UPGRADE-PLAN.md` §9.6: - `src/core` + `src/library` are TypeScript under `strict`. That was E2 and E3, the last of it in #144. - `allowJs` is off. That is this PR. - The declarations are generated from the source. That was E4, #146. - `propTypes` and `prop-types` are gone. That was E5, #145. The demo and the test suites stay JavaScript, as the definition of done allows. ### `allowJs` is off - **The typecheck program is the TypeScript and nothing else:** 418 files before, 137 now. The 281 that left were 234 `.js`, 9 `.jsx` and 36 `.json` files that tsc resolved but never checked, plus the two guard files deleted below. - **A `.ts` file that imports a `.js` module now fails** with TS7016. I measured this with a probe file, then deleted it. During the migration this was `allowJs: true` with `checkJs: false`, so that a converted file could import an unconverted one. - **The typecheck takes 1.56 s, down from 1.80 s**, the median of three runs each. - `tsconfig.build.json` loses its own `allowJs: false`, which it now inherits. ### The E0 guard is deleted `src/toolchain/` was a two-file fixture. It proved that the checker sees `.ts` and that Babel strips it. Its header asked for its deletion "once real converted modules cover the same ground", and they do: the product's TypeScript is built by all three pipelines and imported by every suite. No `.test.ts` is left, because the tests are JavaScript. ### Three casts that still gave the migration as their reason **`PopupContent` re-typed the renderer because it was "still JavaScript".** I removed the cast, and the checker found what it had been hiding: - the popup hands `Render` a `null` `relativePath` and `relativeIndex`; - `Render` passes them on to its children, because it tests `!== undefined`; - `Render`'s prop types said neither could be `null`. They now allow `null`, and the cast is gone. No behaviour changed. **`Data` and `ToggleField` called their casts `UnconvertedComponent`.** Both still need a cast, for reasons of their own: - a registry slot that `utils` types `unknown`, because it sits below the layer that fills it; - a nested document's `initialValues`, which the form layer types as a record and `Data` as `unknown`. The type is now `OpenComponent`, and the comments give those reasons. `Data`'s import is renamed from `UIRenderWithUISetupJs` to `DocumentWithOwnForm`. Its `as unknown as` cast was double; I checked that a single `as` suffices. ### Docs - `CLAUDE.md` says the migration is complete, and that a `.ts` file cannot import JavaScript. - `docs/UPGRADE-PLAN.md` marks the definition of done as met and records the guard's deletion. - The CI comment on the Typecheck step no longer describes unconverted JavaScript. ## Measured | | master | this PR | |---|---|---| | typecheck program | 418 files | 137 files | | `npm run typecheck`, median of 3 | 1.80 s | 1.56 s | | corpus, 38 examples: commits at mount / `translate` calls | 107 / 1012 | 107 / 1012 | | on an edit: commits / `translate` calls | 27 / 64 | 27 / 64 | | DOM after mount and after an edit | | identical, all 38 | | `dist/index.js` | 311,539 bytes | 311,535 bytes | The 4 bytes are `PopupContent`'s alias. Both bundles were built from `git archive` copies in directories of the same name length. ## Gates All exited 0, run on this branch: - `lint:js`, `lint:css`, `typecheck`, `typecheck:contract`; - `docs:props:check`, `docs:views:check`, `css:fixture:check`; - `test:env-flags`, `build`; - `test:coverage`, thresholds included; - `test:pack`, `test:pack:peers`, `test:types`; - `test:react16`, `test:react17`, `test:react19`, 2855 tests each, with no worker crash; - `test:e2e`, 41 tests; - the manifest contract. The suite went from 2857 to 2855 tests: the two were the deleted guard's own. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
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.
What changes
E5: every
propTypesdeclaration is gone, and so isprop-types.rg "prop-types" srcreturns nothing. The package is out ofdevDependencies, and lint rejects an import of it.What is deleted
propTypesblocks in 38 files. The E2 and E3 conversions kept each block on purpose, so this is one deletion rather than forty.components/types.ts, the barrel'sPropTypesre-export, and everyprop-typesandtypeimport.documentHost.tscopied the class's prop types onto the function component, andwithFormSetupmerged them under its own. The four tests that pinned both now pin the rest of what they covered.The descriptions survive, in the props types
TableView,Tabs,Upload,ProgressSteps,AutoSave,asField,asInputDateFieldandToggleField.UIRender's three undocumented props are documented in the publishedUIRender.UIRenderProps, where a host reads them:initialValues,formandembedded. The form layer's props are described in a comment where the layer reads them.propTypesas a fact are reworded:Counter,Listbox,StandaloneTabs,documentHostand the form layer.Not done, deliberately: the vocabulary as TS aliases
The plan's E5 step 2 asked for the
typeproxy to be recreated as aliases, such astype Id = stringandtype Px = number. I measured first:type.String,type.Method,type.Of, and so on.Id(used twice),Fraction,UrlOrBase64OrPreviewandNumberOrString.An alias of a primitive checks nothing. The vocabulary would have been the same documentation in a second place, and 25 of its names would never have been used. The plan records this decision.
No diagnostic a test relied on is lost
formProps/instancewarnings that the plan's §8 flagged were not taken as the contract being met. The declaration itself was wrong. A nestedDatadocument shares its parent's form and is rendered without either prop. EPBDS-16211: fix the bugs the modernization found, and the docs that drifted #139 made both optional.Kept from coming back
prop-typesis still installed, as a dependency ofeslint-plugin-react,react-markdownand the React 16 fixture. An import would therefore resolve and bundle it again.no-restricted-importsnow rejects it in all sevensrcoverrides. I proved this with a probe file in core, in a test and in the demo; each failed with the rule's message.CLAUDE.mdstates the rule: nopropTypesblock. A component's props type, and its JSDoc, are the documentation.Also
README.mdno longer listsprop-typesamong the bundled libraries.docs/SUPPORTED-PROPS.mdis regenerated. OnlyDropdown.tsx's line count changed, from 381 to 364.colGrouppropType that E3 recorded ({styles}) is gone with the rest. The TS type saysstyle.docs/UPGRADE-PLAN.mdrecords E5 and closes its items: the §2 audit line, the §8 row, the E-checks row and the Appendix C checklist. The Appendix C command now looks for a dependency entry, since the lint rule names the package seven times.Found, and left for a change of its own
On React 18, the examples suite's other five allowlist entries match nothing either. Whether any of them still guards something on 16, 17 or 19 is for that change to measure.
Measured
translatecallstranslatecallsdist/index.jsdist/index.js, gzippedisRequiredindist/index.jssrc/core+src/library, TSBoth bundles were built from
git archivecopies in the same directory. Built in the worktree, the same trees measure 322,919 and 311,529 bytes; 322,919 is the figure #144 recorded.Gates
All exited 0, run on this branch:
lint:js,lint:css,typecheck,typecheck:contract;docs:props:check,docs:views:check,css:fixture:check;test:env-flags,build;test:coverage, thresholds included;test:pack,test:pack:peers,test:types;test:react16,test:react17,test:react19, 2842 tests each, with no worker crash;test:e2e, 41 tests;The suite still has 2842 tests. Four tests, in three suites, pinned prop-type forwarding and merging. Each now pins the rest of its subject: the names, the class left as written, and the state shape.
🤖 Generated with Claude Code