chore: make tsc --noEmit clean again — and fix the one real bug it was hiding#561
Merged
Conversation
… was hiding `tsc --noEmit -p tsconfig.json` reported 8 errors on develop. Nothing in the check chain runs it (`nest build` uses tsconfig.build.json, which already excludes the two problem files), so the errors only surfaced as red squiggles in the editor -- and were ignored long enough that a genuine bug hid among them. The real bug: vite.config.ts sets `tsCompiler: 'esbuild'`, but vite-plugin-node@8 narrowed SupportedTSCompiler to 'vite' | 'swc'. The config would not work if anyone ran it. Switched to 'swc', which the project already uses elsewhere (`nest start -b swc`). The rest were configuration mismatches, each fixed at the root rather than silenced: - scripts/generate-framework-api.ts shimmed __dirname from `import.meta.url`, which cannot typecheck under `module: commonjs`. The package IS CommonJS (no "type": "module"), so tsx runs the script as CJS and __dirname is native -- the shim was never needed. Removed. (A separate ESM tsconfig for scripts/ is not an option: scripts/init-server.ts imports src/, which would drag the whole `import x = require(...)` tree into ESM mode.) - vite.config.ts and the migrate template are excluded from the root tsconfig, mirroring tsconfig.build.json. vite@8 is ESM-only and cannot be resolved under `moduleResolution: node`, which `module: commonjs` forces; the template deliberately imports '@lenne.tech/nest-server' because it is copied into consumer projects. - performance-caches.spec.ts marked a method `override` against a base class whose compile-time type is `any` (it comes from a dynamic import), which TS rejects outright (TS4113). - unified-field-whitelist.spec.ts redeclared `email` without an initializer (TS2612). Added `= undefined`, matching every Input class in the codebase. Verification: `tsc --noEmit` now reports 0 errors; the generator still runs; full check green.
kaihaase
force-pushed
the
chore/typecheck-clean
branch
from
July 15, 2026 08:42
b37eedc to
a1628db
Compare
kaihaase
added a commit
that referenced
this pull request
Jul 15, 2026
….28.0 review
Two unrelated bits of housekeeping that were sitting in the working tree.
**.gitignore** — `.lt-dev/` is created per worktree by the `lt dev` CLI and has no business being
tracked.
**.claude/agent-memory/** — written by the review agents during the 11.28.0 (401/403) review. These
are the findings worth carrying forward, not the review prose:
- `security-reviewer/project-exception-wire-format.md` — `HttpExceptionLogFilter` serializes
`{ ...exception }` for REST, so a custom `HttpException` subclass silently changes the wire body
(`name`, `options`) AND breaks `instanceof` against the native Nest exceptions. This is the finding
that would otherwise have shipped a silent breaking change in #559.
- `backend-reviewer/project_401-403-denial-surface.md` — the framework has five permission-denial
layers, and they used to contradict each other. A change to one is a change to none.
- `docs-reviewer/release-version-artifacts.md` — `spectaql.yml` carries the version too and is
derived from `package.json`, but only by `pnpm run docs`, never by `build`. It is therefore
reliably forgotten in release commits.
- `test-reviewer/e2e-isolation-model.md` — e2e files share ONE database per run and execute in
parallel forks, so any unscoped write to global state (a `jwks` wipe, a config mutation) strands
the other files. Pair-run to reproduce; an isolated re-run proves nothing.
Kept separate from #559 and #561 on purpose: neither is part of a code change.
kaihaase
added a commit
that referenced
this pull request
Jul 15, 2026
….28.0 review (#562) Two unrelated bits of housekeeping that were sitting in the working tree. **.gitignore** — `.lt-dev/` is created per worktree by the `lt dev` CLI and has no business being tracked. **.claude/agent-memory/** — written by the review agents during the 11.28.0 (401/403) review. These are the findings worth carrying forward, not the review prose: - `security-reviewer/project-exception-wire-format.md` — `HttpExceptionLogFilter` serializes `{ ...exception }` for REST, so a custom `HttpException` subclass silently changes the wire body (`name`, `options`) AND breaks `instanceof` against the native Nest exceptions. This is the finding that would otherwise have shipped a silent breaking change in #559. - `backend-reviewer/project_401-403-denial-surface.md` — the framework has five permission-denial layers, and they used to contradict each other. A change to one is a change to none. - `docs-reviewer/release-version-artifacts.md` — `spectaql.yml` carries the version too and is derived from `package.json`, but only by `pnpm run docs`, never by `build`. It is therefore reliably forgotten in release commits. - `test-reviewer/e2e-isolation-model.md` — e2e files share ONE database per run and execute in parallel forks, so any unscoped write to global state (a `jwks` wipe, a config mutation) strands the other files. Pair-run to reproduce; an isolated re-run proves nothing. Kept separate from #559 and #561 on purpose: neither is part of a code change.
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.
Problem
tsc --noEmit -p tsconfig.jsonreported 8 errors ondevelop. Nothing in the check chain runs it —nest buildusestsconfig.build.json, which already excludes the two problem files — so the errors only ever surfaced as red squiggles in the editor. They were ignored long enough that a genuine bug hid among them.The real bug
vite.config.tssetstsCompiler: 'esbuild', butvite-plugin-node@8narrowedSupportedTSCompilerto'vite' | 'swc':The config would not work if anyone ran it. Switched to
'swc', which the project already uses elsewhere (nest start -b swc).The rest — fixed at the root, not silenced
scripts/generate-framework-api.tsimport.metacannot typecheck undermodule: commonjs(TS1343)"type": "module"), so tsx runs the script as CJS and__dirnameis native — thefileURLToPath(import.meta.url)shim was never needed. Removed.vite.config.ts,migration-project.template.tsvite@8is ESM-only and unresolvable undermoduleResolution: node(whichmodule: commonjsforces); the template deliberately imports@lenne.tech/nest-serverbecause it is copied into consumer projectstsconfig.build.jsontests/unit/performance-caches.spec.ts:732overrideagainst a base class whose compile-time type isany(it comes from a dynamic import) — TS rejects this outright (TS4113)tests/unit/unified-field-whitelist.spec.ts×3emailredeclared without an initializer (TS2612)= undefined, matching every Input class in the codebaseNote on the approach: a separate ESM
tsconfig.jsonforscripts/is not an option —scripts/init-server.tsimportssrc/, which would drag the wholeimport x = require(...)tree into ESM mode (26× TS1202). Fixing the shim at the source is the only clean route.Verification
tsc --noEmit→ 0 errors (was 8)npx tsx scripts/generate-framework-api.tsstill runs and regenerates the filepnpm run checkgreen: audit, format, lint, tests, build, server-startWhy separate from #559
Pure hygiene, unrelated to the 401/403 work. Reviewable and revertable on its own.
🤖 Generated with Claude Code