Skip to content

feat: add a webjs typecheck command (tsc --noEmit wrapper) - #307

Merged
vivek7405 merged 1 commit into
mainfrom
feat/typecheck-command
Jun 3, 2026
Merged

feat: add a webjs typecheck command (tsc --noEmit wrapper)#307
vivek7405 merged 1 commit into
mainfrom
feat/typecheck-command

Conversation

@vivek7405

Copy link
Copy Markdown
Collaborator

Closes #265

What

webjs ships erasable TypeScript as a first-class authoring mode (strict + noEmit + erasableSyntaxOnly + @webjsdev/ts-plugin) but had no command to run the type checker. The runtime only catches strip-time failures (non-erasable syntax) with a 500; genuine type errors were surfaced by nothing, since webjs check is correctness-only and explicitly does not type-check.

Add webjs typecheck: it resolves the project's OWN typescript/bin/tsc (via createRequire from the app cwd, so it reads the app's tsconfig) and spawns it with --noEmit, passing extra args through (e.g. webjs typecheck --watch), exiting non-zero on a type error so it works as a CI gate. When TypeScript is not installed it prints a clear message and exits non-zero. The framework runs the standard compiler, it does not embed one.

The scaffold now ships a typecheck npm script and typescript as a devDependency, with CONVENTIONS.md documenting it as the separate is-my-TypeScript-valid gate.

A deliberate scope decision

I did NOT add npm run typecheck as a hard step in the scaffold's CI workflow. A CI gate that fails on a fresh scaffold (before the app's example code is verified to type-check cleanly, and @webjsdev/server ships no .d.ts) would be a day-one out-of-box failure, which is worse than a missing gate. The script and the docs make it one line away once the app type-checks.

Tests

test/cli/typecheck.test.mjs spawns the real CLI: a clean TS app exits 0, a type error exits non-zero with the tsc error reported, and a project without TypeScript prints the clear message and exits non-zero. (The success/error fixtures live under the repo so typescript resolves; the no-typescript fixture lives in the OS tmpdir, outside the repo tree.) Scaffold-integration 5/5, full suite 1944.

Docs

Root AGENTS.md CLI reference, packages/cli/AGENTS.md command table, scaffold CONVENTIONS.md.

Scope

CLI + scaffold + docs. No version bump (next release batch).

webjs ships erasable TypeScript as a first-class authoring mode (strict + noEmit + erasableSyntaxOnly + @webjsdev/ts-plugin) but had no command to run the type checker. The runtime only catches strip-time failures (non-erasable syntax) with a 500; genuine type errors were surfaced by nothing, since webjs check is correctness-only and explicitly does not type-check.

Add `webjs typecheck`: it resolves the project's OWN typescript/bin/tsc (via createRequire from the app cwd, so it reads the app's tsconfig) and spawns it with --noEmit, passing extra args through, exiting non-zero on a type error so it works as a CI gate. When TypeScript is not installed it prints a clear message and exits non-zero. The framework runs the standard compiler, it does not embed one. The scaffold now ships a typecheck npm script and typescript as a devDependency, with CONVENTIONS.md documenting it as the separate is-my-TypeScript-valid gate to add to CI once the app type-checks cleanly. Not auto-added to the scaffold CI to avoid a day-one failure before the app is verified to type-check.

Closes #265
@vivek7405 vivek7405 self-assigned this Jun 3, 2026

@vivek7405 vivek7405 left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the command logic, the test, and the one judgment call. The command is right: it resolves the project's own typescript/bin/tsc via createRequire from the app cwd (so it reads the app's tsconfig), spawns it with --noEmit and a passthrough for extra args, and propagates the child exit code so it works as a CI gate; tsc with a bare flag still reads tsconfig, confirmed by the clean-exits-0 and type-error-exits-nonzero fixtures. Graceful degradation prints the npm install -D typescript fix and exits non-zero. The test spawns the real CLI for all three paths and cleans its fixtures (no stray dirs in git status, the no-typescript fixture lives in the OS tmpdir outside the repo tree so typescript is genuinely unresolvable).

The one decision worth checking was omitting the scaffold CI gate, and it is correct: @webjsdev/server ships no .d.ts, so a fresh scaffold importing createRequestHandler from it would emit TS7016 under strict, meaning a hard typecheck gate in the scaffold CI would fail on day one. Shipping the script and documenting it, while leaving the gate to the author once the app type-checks, is the right out-of-box posture. Full suite 1944 (the known flaky CSP-nonce test passed). Good to merge once CI is green.

@vivek7405
vivek7405 merged commit 0eb4e9f into main Jun 3, 2026
5 checks passed
@vivek7405
vivek7405 deleted the feat/typecheck-command branch June 3, 2026 11:16
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.

Add a webjs typecheck command (tsc --noEmit wrapper)

1 participant