ryanahamilton opened a new pull request, #71563:
URL: https://github.com/apache/airflow/pull/71563

   `React.FC` adds nothing over annotating the props parameter directly, and 
the UI packages were split between the two styles — 13 components used 
`React.FC` while 540+ others annotated the parameter. The same split showed up 
in type references, where `React.ReactNode` / `React.ReactElement` sat 
alongside the dominant `import { type ReactNode } from "react"` style.
   
   Every React package here compiles with the automatic JSX runtime (`"jsx": 
"react-jsx"`), so no file needs a `React` import at all — the namespace 
survived only as habit. This removes both patterns and adds ESLint rules so 
they cannot creep back in.
   
   ### Cleanup
   
   | Package | `React.FC` | Namespaced type refs | Value refs |
   |---|---|---|---|
   | `airflow-core/src/airflow/ui` | 13 | 79 | 30 |
   | simple auth manager UI | 0 | 6 | 0 |
   | edge3 plugin UI | 0 | 9 | 3 |
   | react plugin template | 0 | 0 | 0 |
   
   Three props types gained `readonly`: `react/prefer-read-only-props` is 
already at `ERROR` but cannot see through `React.FC<Props>`, so it only starts 
applying once the type moves onto the parameter.
   
   ### Enforcement
   
   Two rules, because neither alone is sufficient:
   
   - **`@typescript-eslint/no-restricted-imports`** bans the `React` 
default/namespace import. With the import gone, TypeScript also reports 
`TS2686` on any leftover value-position `React.x`.
   - **`no-restricted-syntax`** bans namespaced *type* references. This one is 
load-bearing: `@types/react` declares `export as namespace React`, so 
`React.FC<Props>` type-checks with **no import at all** — 4 of the 13 
`React.FC` files did exactly that, and the import ban alone would have missed 
them.
   
   The `FC` selector is deliberately narrow — it fires only when `FC` types a 
variable whose initializer is an arrow function, i.e. a component *definition*. 
Annotating a component *value* stays legal, which two existing usages rely on 
(`components/ui/ButtonGroupToggle.tsx`, `pages/ReactPlugin.tsx`).
   
   ### Notes for reviewers
   
   - **`src/main.tsx` is the one exemption**, via `eslint-disable` with a 
comment. It republishes the host's React on `globalThis` for plugin bundles, 
which are built as UMD against a `React` global (`rollup output.globals: { 
react: "React" }`). Changing the import form would change which object plugins 
receive, so that file is a comment-only diff with no runtime change.
   - The rules caught two bare `FC` component definitions that a text search 
for `React.` could not see, in the edge3 and plugin-template `main.tsx`. Fixing 
the template stops new plugin UIs being scaffolded with the pattern.
   - No newsfragment: internal refactor with no user-visible behaviour change.
   
   ### Verification
   
   ESLint reports 0 errors on both airflow-core UIs and `tsc` is clean; the 141 
remaining warnings are pre-existing `react-refresh/only-export-components` ones 
in files this PR does not touch. 854 unit tests pass. `prek run --stage 
pre-commit` passes with no file modifications.
   
   edge3 needed a workaround to verify: its ESLint currently cannot start at 
all (a `"ajv@<8.18.0"` override in its `package.json` bumps ESLint's own 
`ajv@6` to `ajv@8`, and ESLint 10 needs ajv 6's `json-schema-draft-04.json`), 
and its `ts-compile-lint-edge-ui` prek hook passes vacuously because 
`scripts/ci/prek/ts_compile_lint_edge.py` resolves its filter path against the 
repo root while the nested config passes paths relative to `providers/edge3/`, 
so it filters every file out. Both reproduce on a clean `main` and are 
unrelated to this PR; I verified edge3 by temporarily pointing its ESLint at a 
working ajv and running its real config — **13 violations of the new rules 
before the cleanup, 0 after**, with every other rule count identical. Its three 
pre-existing `tsc` errors are byte-identical before and after. Happy to file 
those separately.
   
   ---
   
   ##### Was generative AI tooling used to co-author this PR?
   
   - [X] Yes — Claude Code (Opus 5)
   
   Generated-by: Claude Code (Opus 5) following [the 
guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions)


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to