Skip to content

The four repo-root vitest.setup.* files are in zero tsc programs — #3476 one directory up #3515

Description

@yinlianghui

Observation-class finding, tripped over while implementing #3476 (PR #3513). Nothing a user hits today — recording it so it does not stay invisible. Not fixed in #3513: the fix lands in a root tsconfig, which was outside that task's file fence.

The gap

Four checked-in files at the repo root are compiled by nothing:

vitest.setup.base.ts
vitest.setup.dom.tsx
vitest.setup.dom-light.tsx
vitest.setup.tsx

Measured on the #3476 branch (same result on origin/main @ f995a45):

$ ./node_modules/.bin/tsc -p tsconfig.json        --listFilesOnly | grep -c 'objectui/vitest.setup.dom.tsx'
0
$ ./node_modules/.bin/tsc -p tsconfig.scripts.json --listFilesOnly | grep -c 'objectui/vitest.setup.dom.tsx'
0

Why nothing reaches them:

  • They sit at the repo root, outside every workspace package (pnpm-workspace.yaml: packages/*, examples/*, apps/*, docs), so turbo run type-check — which is driven by package.json scripts — structurally cannot see them. Same reason scripts/ was uncovered until [ci] scripts/ 在零 tsconfig 覆盖内:turbo type-check 从不检查 scripts/__tests__/*.ts——一批门禁 pin 测试自身无类型门 #3494.
  • Root tsconfig.json's include is packages / examples / apps; tsconfig.scripts.json's is scripts/**. Neither matches the root directory itself.
  • They are never imported by anything under packages / examples / apps either, so no gated program pulls them in transitively. Every consumer names them as a Vitest setupFiles runtime path string (setupFiles: ['../../vitest.setup.tsx'], path.resolve(import.meta.dirname, '../../vitest.setup.dom.tsx'), ...). The one real import edge is internal: vitest.setup.dom.tsx line 15 imports ./vitest.setup.base.

The only program that does contain them is the root tsconfig.node.json (no include, so it defaults to the whole root directory) — and no script anywhere runs that file, so it is not a gate.

Why it is worth recording

This is exactly the #3476 shape one directory up, and the #3494 shape one directory over: a checked-in .ts/.tsx file that reads as ordinary maintained source while no tsc invocation has ever looked at it.

The content is not trivial plumbing either. vitest.setup.dom.tsx decides which of four side-effect package graphs get registered before the dom-heavy project runs, and vitest.setup.base.ts is imported by it. Drift there does not fail loudly with a type error — it fails as a confusing "component not registered" in whichever test happens to depend on the registration.

Impact today: nil. They are small and currently correct; a break would surface as a red test run rather than silently. That is why this is finding and not queued.

Not the same as the per-package setup files

Checked while measuring, so nobody re-checks it: the ./vitest.setup.ts that seven package vitest configs reference (plugin-kanban, plugin-calendar, plugin-detail, plugin-gantt, plugin-charts, plugin-form, plugin-designer) all exist, and they live inside their package, so they are reachable by that package's own tsconfig. No ghost entries there.

Shape of a fix (for whoever picks it up)

Not obvious enough to prescribe — the options differ in blast radius and want measuring, the way #3494 measured allowJs:

  1. Add the root vitest.setup.* files to tsconfig.scripts.json's include. Cheap, but that project is named and documented for scripts/, and it sets allowJs: true — which is the option that turned five @ts-expect-error comments stale in ci(scripts): 用独立 tsconfig.scripts.json 给 scripts/ 补上类型门 (#3494) #3498 and is still doing so in main 的 Type Check job 全红:#3489 与 #3498 的语义冲突,check-doc-links.test.ts@ts-expect-error 在 allowJs 下变成 TS2578 #3504. A .tsx also needs jsx and DOM lib, which that project does not set.
  2. A small dedicated root project for them, mirroring how [ci] scripts/ 在零 tsconfig 覆盖内:turbo type-check 从不检查 scripts/__tests__/*.ts——一批门禁 pin 测试自身无类型门 #3494 handled scripts/, wired into ci.yml next to type-check:scripts. Most consistent with precedent; costs one more config and one more CI step.
  3. Widen the root tsconfig.json and give it a runner. Largest blast radius — that file is currently the editor config and nothing runs it; making it a gate is a separate decision with its own error backlog.

Whichever route, the reverse verification is the same as #3513's: plant a real type error in one of the four files and confirm the chosen gate goes red, having predicted that direction first.

Related: #3476 / PR #3513 (this file family's neighbour), #3494 / PR #3498 (scripts/), #3305 (the console node project), #3504 (the live allowJs / TS2578 interaction option 1 would inherit).


Generated by Claude Code

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions