Skip to content

feat: add a typescript check - #327

Merged
alexander-akait merged 1 commit into
mainfrom
feat/typescript-check
Sep 11, 2026
Merged

feat: add a typescript check#327
alexander-akait merged 1 commit into
mainfrom
feat/typescript-check

Conversation

@alexander-akait

Copy link
Copy Markdown
Member

Summary

The third check, and the first that is not a linter. Run it with { use: "typescript" } or just "typescript": it builds the program a tsconfig.json describes and reports its diagnostics as webpack errors and warnings, so a type error in a module nothing imports yet is reported rather than waiting for something to import it. Emit is forced off — webpack writes the output.

It also answers whether the checks API is really extensible. It is: the adapter is one file plus a schema, and the only plugin change a type checker needed is the one below.

A type checker does not fit a linter's shape, and the contract already allowed for it. The adapter declares no resultPath, because a diagnostic belongs to the program rather than to the file the plugin handed over. The one plugin change follows from that: a check with no resultPath is now given the whole file list every compilation rather than only what changed, since there is nothing to report a file it was never given from. threads is not honoured either, TypeScript spreading its own work, and that is stated in the README.

Two things turned up while testing it against the syntax the README already shows:

  • A check could not be named. checks: ["eslint"] threw `use` needs the name of a built-in check, though the README has shown that form since the one-mode docs merged — my own snippet, and wrong. An entry may now be the name alone, which is what a check with nothing to configure wants.
  • A new suite's fixtures need adding to the lint ignores, which is why the three existing suites are listed there. Without it the repo lints its own deliberately-broken fixtures.

What kind of change does this PR introduce?

feat

Did you add tests for your changes?

Yes — test/typescript/typescript.test.js, six cases over two fixture projects: a clean program reports nothing, a type error becomes a webpack error naming the file and the TS code, a file webpack never built is still checked, an unreadable configFile surfaces TypeScript's own TS5083 rather than a message of ours, a formatter written in the configuration is used, and reportAs turns the errors into warnings. test/unified/unified.test.js gains the named-check case.

Does this PR introduce a breaking change?

No. The new check is opt-in, and naming a check is additive. The resultPath change only affects a check that declares none, of which there were none before this one.

If relevant, what needs to be documented once your changes are merged or what have you already documented?

README.md here: a TypeScript section with typescriptPath, configFile and compilerOptions, what differs from the linters, and the intro and install lines. typescript >= 5 is an optional peer in package.json. The webpack.js.org page wants the section after release.

Use of AI

AI was used. Claude Code prototyped the TypeScript compiler API against a fixture before writing the adapter, then wrote it, the tests and the documentation, and ran the suite, lint, audit and both dist entry points. While verifying it in watch mode it found a pre-existing hole it has reported rather than fixed here: the plugin registers no fileDependencies, so webpack does not watch a file no module imports — measured on main, editing an unimported .scss rebuilds nothing and its Stylelint error never clears. That belongs in its own change, for every glob-reading check at once.

🤖 Generated with Claude Code

https://claude.ai/code/session_01GzZci4NQeiqwdrVfd7dGXy


Generated by Claude Code

Run it with `{ use: "typescript" }`, or just `"typescript"`. It builds the
program a `tsconfig.json` describes and reports its diagnostics, so a type
error in a module nothing imports yet is reported rather than waiting for
something to import it. Emit is forced off: webpack writes the output.

A type checker does not fit the shape a linter does, and the contract already
allowed for that. It declares no `resultPath`, because a diagnostic belongs to
the program rather than to the file the plugin handed over — and a check that
cannot attribute a result now gets the whole file list every compilation
rather than only what changed, since there is nothing to report a file it was
never given from.

Two things found while testing it against the documented syntax. A check could
not be named — `checks: ["eslint"]` threw, though the README has shown it
since the one-mode docs landed — so an entry may now be the name alone, which
is what a check with nothing to configure wants. And the fixtures of a new
suite need adding to the lint ignores, which is why the three existing suites
are listed there.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GzZci4NQeiqwdrVfd7dGXy
@alexander-akait
alexander-akait merged commit 976f4c3 into main Sep 11, 2026
13 checks passed
@alexander-akait
alexander-akait deleted the feat/typescript-check branch September 11, 2026 09:26
This was referenced Sep 11, 2026
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.

1 participant