Catch TypeScript Type Errors in Vitest Before CI Fails
Use Vitest typecheck to run tsc over test and source files, catching type errors runtime tests miss.
25 Jul 2026, 05:43 UTC

Runtime tests pass, but types still break
Vite strips TypeScript types with esbuild before your tests run. esbuild is the JavaScript bundler Vite uses to transform and remove type annotations. That keeps test execution fast, but it also means a test file can import a function with the wrong argument shape and still pass if the runtime values happen to work. Vitest's typecheck mode closes that gap by running tsc, the TypeScript compiler, over your test and source files as part of the Vitest workflow.
If you already run vitest locally and in CI, adding typecheck gives you a static gate without introducing a separate test runner. It is not a replacement for tsc --noEmit across your whole application, but it catches type errors in code that tests actually import.
Configure typecheck in vitest.config.ts
Add a typecheck block to your Vitest config. This example enables type checking and points it at test and source directories:
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
include: ['src/**/*.test.ts'],
},
typecheck: {
enabled: true,
include: ['src/**/*.ts', 'src/**/*.test.ts'],
exclude: ['src/**/*.d.ts'],
},
});
Run commands from the project root where vitest.config.ts lives. No elevated permissions are required; the command reads local files and writes only to standard output.
Run typecheck locally and in CI
Use npx vitest typecheck to type-check without executing tests:
npx vitest typecheck
Or combine type checking with a test run:
npx vitest run --typecheck
Both commands exit with a non-zero status when TypeScript reports errors, which makes them suitable as a CI gate. Before merging, check the resolved compiler and Vitest version:
npx vitest --version
Config shape and default checker behavior can change between Vitest major versions, so verify the installed release against its documentation before relying on this in CI.
Concrete verification step
To confirm the gate works, temporarily introduce a type error in a test file—for example, pass a string where a number is expected—and run npx vitest typecheck. The command should fail and print TypeScript diagnostics. Revert the change and confirm the command exits zero. Do not leave the deliberate error in the repository.
Trade-offs and limitations
- Static only. Passing typecheck does not prove runtime behavior. Vite still strips types with esbuild, so a type-correct test can still fail at runtime.
- Scope limits. Typecheck covers files imported by tests and the patterns in
include. Application code never imported by a test is not checked here; use a separatetsc --noEmitstep for full-project coverage. - Path aliases and resolution. TypeScript path aliases, custom module resolution, and non-standard compiler options must be declared in the referenced
tsconfig.json. Mismatches produce spurious type errors. - Performance. Whole-program type checking can slow local feedback and CI cycle times in large monorepos.
Practical check before enabling
- Add
typecheck: { enabled: true }tovitest.config.ts. - Run
npx vitest typecheckon a clean branch and note the exit code. - Create a branch with a deliberate type error in a test file and confirm the command exits non-zero.
- Revert the error branch and add the typecheck step to your CI pipeline after unit tests.
To roll back, remove the typecheck block from vitest.config.ts.
Typecheck is a useful supplement to Vitest runtime execution, not a substitute for a full TypeScript build pass. Verify it against your installed Vitest version before making it a required CI check.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.