/commands/typescript/tsc-noemit-type-check
tsc --noEmit: type check a TypeScript project without emitting files
- tool
- TypeScript
- versions
- TypeScript 2.x+, TypeScript 7.0
- os
- any
npx tsc --noEmit runs the TypeScript type checker on the project described by tsconfig.json and writes no .js, .d.ts or source map files. It prints every type error and exits with a non-zero status when there are any, which makes it the standard type-check step in CI next to a bundler that only strips types.
Check a project
npm init -y >/dev/null
npm pkg set type=module
npm install --silent --no-audit --no-fund --save-dev typescript@7.0.2 >/dev/null 2>&1
npx tsc --init >/dev/null
mkdir src
cat > src/user.ts <<'EOF'
interface User { name: string; age: number }
export const user: User = { name: "Ada", age: "36" };
export const label = user.nmae;
EOF
npx tsc --noEmit
status=$?
ls src
exit $statusOutput · exit 1
src/user.ts(2,42): error TS2322: Type 'string' is not assignable to type 'number'. src/user.ts(3,27): error TS2339: Property 'nmae' does not exist on type 'User'. user.ts
Both errors are reported and src/ still holds only the source file: no user.js was written. The exit status is 1 with --noEmit; a normal tsc build that finds errors still writes the output files and exits with 2.
Variants
| Command | What it does |
|---|---|
| npx tsc --noEmit | Type check the project from tsconfig.json in the current directory |
| npx tsc --noEmit -p tsconfig.app.json | Use another config file or a folder that contains one |
| npx tsc --noEmit --watch | Re-check on every save |
| npx tsc --noEmit --incremental --tsBuildInfoFile .tsbuildinfo | Cache results so repeated checks are faster |
| npx tsc --noEmit --pretty false | One line per error, easier to parse in CI logs |
| npx tsc -b | Build a project with references; for checks set noEmit or emitDeclarationOnly in the referenced configs |
Add it to package.json
{
"scripts": {
"typecheck": "tsc --noEmit"
}
}Then npm run typecheck runs it locally and in CI. Setting "noEmit": true in tsconfig.json has the same effect for every tsc call, which suits projects where a bundler always produces the JavaScript.
Pitfalls
- Files outside include. tsc checks only the files that
include/filesintsconfig.jsonselect (all.tsfiles below the folder by default). A file outside them is never checked.npx tsc --listFilesOnlyshows the list. - Passing a file name (
tsc --noEmit src/a.ts) ignorestsconfig.json; TypeScript 6.0 and later stop with error TS5112 instead. See tsc file.ts and tsconfig.json. - skipLibCheck hides errors inside dependencies'
.d.tsfiles; that is usually wanted, but it can mask a broken type package. - Typical errors it reports: TS2322 not assignable, TS2339 property does not exist, TS2307 cannot find module.
Confirm it worked
Introduce a deliberate type error, run the command and check that it fails, then remove the error and check that it exits 0 with no output.
FAQ
Why use tsc --noEmit when my bundler already compiles TypeScript?
Bundlers such as Vite, esbuild and swc only strip types; they do not type check. tsc --noEmit is the step that actually reports type errors, so it belongs in CI or a pre-commit hook.
Is tsc --noEmit faster than a normal build?
A little, because nothing is written, but the type checking itself is the slow part. Add --incremental with a tsBuildInfoFile, or use TypeScript 7, which is a native compiler, for larger speed-ups.
Can I check only the files changed in a commit?
Not reliably. Types flow across files, so a change in one file can break another. Check the whole project; incremental mode keeps repeated runs fast.