Skip to content

EPBDS-16211 E2: the field components and their helpers, as TypeScript - #138

Merged
AlexSamBY merged 1 commit into
masterfrom
e2-ts-sixth-batch
Oct 1, 2026
Merged

AlexSamBY merged 1 commit into
masterfrom
e2-ts-sixth-batch

Conversation

@AlexSamBY

Copy link
Copy Markdown
Member

What changes

The field components and the helpers the converted files already leaned on become TypeScript.

  • Components, as .tsx: Input, InputDate and Table.
  • Modules, as .ts:
    • domProps, with a typed omitProps;
    • inputs/validationRules;
    • inputs/normalizers;
    • utils/timers, which holds useTimers.

All seven are renamed with git mv. Git detects every rename (53–96% similarity), so their history follows.

file notes
Input.tsx InputProps
InputDate.tsx InputDateProps, over rc-picker's own PickerProps
Table.tsx TableProps and TablePartProps; the family's structure is unchanged
domProps.ts omitProps returns Record<string, unknown>, not the Object its JSDoc said
validationRules.ts ValidationResult
normalizers.ts parameter types from what each body needs
timers.ts Timers, with setTimeout's extra arguments typed through to the callback

LocalDraftTableRow's last three component casts go, so no .tsx file casts a component any more. What is left of UnconvertedComponent types the registry slots (Active.Field, Active.UIRender) and the engine's import cycle. Row's cast of the omitProps result is gone too.

A throwaway probe of seven wrong uses failed on all seven, and its correct counterparts compiled:

  • an onRemove taking a number;
  • an InputDate onChange taking a number;
  • a string striped;
  • omitProps on a string;
  • maxLength('5');
  • phone(5);
  • a timer callback whose arguments do not match.

What the checker found

  • The draft row hands its fields an unknown error. fieldErrors[name] reaches Input/InputDate as error. It is normally a message. Under validate: 'maxLength' it is the function the factory returns, the bug EPBDS-16211 E2: the five components #132 converted, as TypeScript #133 recorded, and React does not render it. A commented cast where it is read says so.
  • InputDate passes rc-picker a resize that rc-picker does not declare. A probe showed that rc-picker drops it: no element it renders carries the attribute, the open panel included. It is typed rather than removed, so the runtime is unchanged.
  • password keeps its last value on itself for password.confirm. TypeScript recognises a function's own properties only when they are assigned at the top level, so the assignment inside the function is a cast.

No runtime change

Every edit is a type, a cast or a comment. dist/index.js went from 327,387 to 327,369 bytes, 18 smaller, because three cast aliases are gone and one is added.

The prop-reference generator

It statically parses domProps and Table.

  • It finds them by extension, because pack() already looked for .ts.
  • It matches export const ENGINE_PROPS = [ literally, so the two lists stay unannotated.
  • docs/SUPPORTED-PROPS.md is regenerated. Only the paths and Table's line count changed.

Measured

  • The corpus is identical to master. Over the 38 examples through the published entry: commits at mount 107, translate calls 1013, and 27 / 64 on an edit. The DOM is identical after mount and after an edit.
  • TypeScript is now the larger half. src/core + src/library hold 71 TypeScript files, 10,806 lines (was 64 and 9,989), against 86 JavaScript files, 9,396 lines (was 93 and 10,111). That is 53.5% of the lines, up from 49.7%.

Housekeeping

  • Every mention of domProps.js names domProps.ts. There were 22 in 17 files: component and engine comments, tests, the generator, the curation, and a comment in the CI workflow.
  • The other renamed files' mentions follow too. That covers the three coverage thresholds in jest.config.js and nine comments. Two of the comments are in LESS (_semantic.less, tooltip.less) that survives compilation, so public/static/ui-render.built.css is rebuilt. A comment that told history ("Table.js used to be a 24-line wrapper") now names the component without an extension.
  • The plan records the batch. docs/UPGRADE-PLAN.md §9.6-E2 has the note.

A miss of my own, which the gates caught

The first run of the gate set failed test:coverage: "Coverage data for ./src/core/components/Table.js was not found", and the same for Input.js and InputDate.js. The three thresholds still named the old files.

My stale-path check had passed, but vacuously. On this machine git grep -E with \b matches nothing: 0 hits where the same search without \b finds 9. Every check in this PR was rerun word-bounded with git grep -P, next to a control search for a known hit.

That rerun also found older stale mentions, which are fixed here as well:

Gates

The final run, after the fixes above, exited 0 on every gate:

  • lint:js, lint:css, typecheck, typecheck:contract;
  • docs:props:check, docs:views:check, css:fixture:check;
  • test:env-flags, build;
  • test:coverage, thresholds included. Every touched file's coverage is unchanged, and validationRules' and LocalDraftTableRow's partial branches are the same expressions as on master;
  • test:pack, test:pack:peers, test:types;
  • test:react16, test:react17, test:react19, 2908 tests each, with no worker crash;
  • test:e2e, 41 tests;
  • the manifest contract.

In the demo on the dev server:

  • input example: typing kept the value, and the wrapper took the done class. That is the path the done cast covers.
  • nestedDataKind example: it renders four ui tables. None of their 58 cells carries an empty class, the cells hold 44 fields, and the draft row's "Add line" button is there.
  • Console: no error.

The demo has no date field, since the one date-typed meta is an orphan, so InputDate is covered by its suites.

🤖 Generated with Claude Code

Input, InputDate and Table become .tsx, and domProps, inputs/
validationRules, inputs/normalizers and utils/timers become .ts (git
mv, so their history follows). LocalDraftTableRow's last three
component casts go: no .tsx file casts a component any more.

The checker's findings, each typed as the code behaves: the draft row
hands its fields an `unknown` error, which under validate: 'maxLength'
is the function the factory returns (a cast at the read, with the
note); InputDate passes rc-picker a `resize` it does not declare and
drops (measured: no element carries it, the open panel included);
`password` keeps its last value on itself, which TypeScript only sees
through a cast.

omitProps returns Record<string, unknown> instead of the `Object` its
JSDoc said, which retires Row's cast. Every mention of a renamed file
follows it, the coverage thresholds included; the first gate run caught
three thresholds my stale-path check had missed, because `git grep -E`
with \b matches nothing on this machine. Rechecked with -P: six older
comments naming Data.js (missed by #133) and five naming TooltipPop.js
are fixed too. docs/SUPPORTED-PROPS.md and the built CSS are
regenerated.

Measured: the 38-example corpus is identical to master (107 / 1013 /
27 / 64, same DOM); dist/index.js 327,387 -> 327,369 bytes;
TypeScript is 53.5% of src/core + src/library lines, was 49.7%.
@AlexSamBY
AlexSamBY merged commit 23203af into master Oct 1, 2026
5 checks passed
@AlexSamBY
AlexSamBY deleted the e2-ts-sixth-batch branch October 1, 2026 08:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant