Safeguard
Developer Tools•

How do you make a TypeScript build fail on type errors?

TypeScript emits JavaScript even when types fail unless you act. How noEmitOnError and a separate noEmit check in CI keep type errors out of releases.

Safeguard Security Team
3 min read

Run the compiler as a required CI check that exits non-zero on any error, and set noEmitOnError so a failed build writes no output. The TypeScript reference says noEmitOnError defaults to false, so by default the compiler can produce JavaScript even when it reported errors.

What the reference says

The tsconfig reference describes noEmitOnError as: do not emit compiler output files such as JavaScript, source maps or declarations if any errors were reported. It notes the default is false, which suits watch style work where you want to see results before every error is fixed. That default is convenient on a laptop and unsafe as a release default.

The Node.js TypeScript page uses noEmit in its recommended config for projects that only execute .ts files. That variant writes nothing and acts as a pure check.

Two settings, two jobs

SettingEffectBest for
noEmitOnErrorEmits nothing if any error is reportedBuilds that produce JavaScript
noEmitNever emits, only checksCI type check, or projects Node runs directly

Why this matters for security

Strict flags only help if they gate something. If a build prints type errors and still produces a bundle, and the pipeline only looks at the bundle, the errors are advice. A missing null check that the compiler found can then ship. Make the rule binary: errors mean no artifact.

Steps

  1. Turn on strict and the extra flags you want, see tsconfig flags beyond strict.
  2. Add noEmitOnError: true to the build tsconfig.
  3. Add a CI job that runs the compiler with --noEmit on every pull request. Name it clearly, such as "typecheck".
  4. Mark that job as a required status check on the protected branch.
  5. Make the release job depend on a passing typecheck job, so a manual rerun of the build step cannot skip it.
  6. Do not hide errors with @ts-ignore comments without a reason. Prefer @ts-expect-error with a note, which fails when the error disappears, so stale suppressions get noticed.
  7. Count suppression comments in CI and fail if the number grows.

Compiler versus bundler

Many bundlers and fast transpilers strip types without checking them. They are fast because they skip the type check. If your build uses one, the compiler check must run separately, otherwise nothing enforces your types. This is the same gap described in running TypeScript directly in Node.

What a passing check does not mean

A clean type check says the types agree. It does not say input is validated or that dependencies are safe. Keep schema validation at boundaries and scan your lockfile.

Try it yourself

Open the pull request gate demo and watch a failing check block a change. Your typecheck job should behave the same way.

Click through it at your own pace, or open it full screen.

Safeguard policies and gates can add dependency checks to the same pull request flow. A free scan shows your lockfile's findings.

Quick check

Is noEmitOnError on by default?

No. The TypeScript reference says it defaults to false.

Do I still need a typecheck job if my bundler builds fine?

Yes. Bundlers that strip types do not check them, so run the compiler as its own required check.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.