Skip to content

fix: opt generated projects into @types globals per target (TS 6)#120

Merged
PAMulligan merged 2 commits into
mainfrom
119-generated-projects-fail-pnpm-typecheck-under-typescript-6-shared-tsconfig-missing-types-field
Jun 13, 2026
Merged

fix: opt generated projects into @types globals per target (TS 6)#120
PAMulligan merged 2 commits into
mainfrom
119-generated-projects-fail-pnpm-typecheck-under-typescript-6-shared-tsconfig-missing-types-field

Conversation

@PAMulligan

Copy link
Copy Markdown
Contributor

Fixes #119

Problem

Every project generated by setup-project.sh failed pnpm typecheck with TS2591 (process), TS2584 (console), and TS2304 (setTimeout) on all five targets. The script installs typescript@latest, which now resolves to TypeScript 6 — and TS 6 removed the automatic inclusion of node_modules/@types/*. The copied templates/shared/tsconfig.json had no types field, so @types/node was installed but never loaded. CI stayed green because the typecheck-templates job uses per-target snippet tsconfigs that do set types, with a lockfile-pinned toolchain.

Fix

Where the fix lives (acceptance criterion 3): per-target tsconfig templates, structured so the snippet tsconfigs extend the same files generated projects receive — drift between CI and generated output is now structurally impossible rather than comment-enforced.

  • templates/shared/tsconfig.jsontsconfig.base.json (content unchanged), plus two thin per-target configs:
    • tsconfig.node.json"types": ["node"], used by node, lambda, railway, fly
    • tsconfig.cloudflare.json"types": ["@cloudflare/workers-types", "node"], used by cloudflare
  • Generated projects get the per-target file as api/tsconfig.json extending the copied api/tsconfig.base.json.
  • templates/snippets/tsconfig.{node,lambda,cloudflare}.json now extend the per-target templates and drop their own types — the typecheck-templates job type-checks through the exact configuration that ships.
  • The cloudflare target now installs @cloudflare/workers-types (referenced by its types entry; pnpm doesn't expose transitive packages for type resolution). The sync NOTE in the script claimed this was "added per-platform below" but it never was.
  • typescript is pinned to its major (^6) in the generated dev deps so the next TS major can't silently break generation; comment updated with the rationale. Snippets already pin ^6.0.2.
  • node-server and docker Dockerfiles copy tsconfig.base.json into the build stage so in-image pnpm build keeps working.

CI gap closed

New generated-projects matrix job runs the real setup-project.sh for all five targets and type-checks the result. Deliberately no lockfile — it installs whatever pnpm add resolves that day, so a dependency release that breaks fresh projects fails in CI instead of only on user machines (exactly how this regression shipped).

Verification

  • Reproduced first on the old config: fresh --node project, typescript@6.0.3 → the exact TS2591/TS2584/TS2304 errors from the issue.
  • After the fix, generated all five targets fresh: every project resolves typescript@6.0.3 (pin written as ^6.0.3) and passes pnpm typecheck.
  • pnpm build (tsc emit, the Docker build path) passes on the node target; dist/index.js emitted.
  • All three snippet tsconfigs pass with the pinned snippet lockfile through the new extends chain.
  • ESLint (typed rules via projectService) resolves the extends chain; generated-project lint errors drop from 53 to 11. The remaining 11 are pre-existing stylistic findings in the snippet sources, unrelated to this issue.

🤖 Generated with Claude Code

setup-project.sh copied a single shared tsconfig with no "types" field
into every generated project. TypeScript 6 removed the automatic
inclusion of node_modules/@types/*, so freshly generated projects
failed pnpm typecheck with TS2591/TS2584/TS2304 (process, console,
setTimeout) on all five targets.

- Split templates/shared/tsconfig.json into tsconfig.base.json plus
  per-target tsconfig.node.json (types: ["node"], also used by lambda,
  railway, and fly) and tsconfig.cloudflare.json (adds
  @cloudflare/workers-types). Generated projects get the per-target
  file as tsconfig.json plus the copied base. The snippet tsconfigs
  now extend the same per-target files, so the typecheck-templates CI
  job checks exactly the configuration generated projects receive.
- Install @cloudflare/workers-types for the cloudflare target; the
  "types" entry references it and pnpm does not expose transitive
  packages for type resolution.
- Pin typescript to its major (^6) in the generated dev dependencies
  so a future TS major cannot silently break generation again.
- Copy tsconfig.base.json in the Docker build stage (node-server and
  docker templates) so pnpm build keeps working in-image.
- Add a generated-projects CI matrix job that runs setup-project.sh
  for every target and type-checks the result against freshly
  resolved dependencies - the gap that let this regression ship.

Fixes #119

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions github-actions Bot added area: scripts Automation scripts area: templates Starter templates area: ci-cd CI/CD workflows labels Jun 13, 2026
The script was committed mode 100644, so the documented
./scripts/setup-project.sh invocation (and the new generated-projects
CI job) fails with "Permission denied" on Linux and macOS. Never
noticed locally because Git Bash on Windows ignores the exec bit.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@PAMulligan PAMulligan self-assigned this Jun 13, 2026
@PAMulligan PAMulligan merged commit 88f24f8 into main Jun 13, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: ci-cd CI/CD workflows area: scripts Automation scripts area: templates Starter templates

Projects

Development

Successfully merging this pull request may close these issues.

Generated projects fail pnpm typecheck under TypeScript 6 — shared tsconfig missing types field

1 participant