Safeguard
Developer Tools•

Does TypeScript protect a front end from untrusted data at runtime?

TypeScript types are erased at runtime, so they do not validate API responses or messages. See where to validate and which type habits create false safety.

Safeguard Security Team
3 min read

No. TypeScript types are erased when your code runs, so they enforce nothing against a malicious or malformed caller. They catch mistakes in your own code at build time. Data from the network, storage and messages still needs runtime validation at each trust boundary.

What types do and do not do

OWASP's JavaScript and TypeScript Security Cheat Sheet is blunt about this: types are erased at runtime, so TypeScript alone enforces nothing against a malicious or malformed caller. Turning on strict mode in tsconfig.json helps catch accidental unsafety in your own code, but the sheet calls it a code quality control, not a trust boundary.

A typical bug looks like this. You declare that an API response has a string name field. The server, a proxy, a cached copy or an attacker returns something else. At runtime nothing checks, your component receives an object where it expected a string, and a downstream sink such as an HTML renderer does something unexpected.

Habits that create false confidence

HabitWhy it misleads
Using anyDisables type checking for that value, so treat it as a hole in every check
Type assertions with asSilence the compiler without changing runtime values
Non-null assertions with !Same: the compiler stops warning, the value is unchanged
Hand written interfaces for API responsesThey describe a hope, not a verified shape

The sheet suggests unknown as the safe default for values of unknown type, since it forces you to narrow before use.

Where to validate

OWASP names the places: network responses, postMessage payloads and storage reads. Use a runtime schema validator at each of them, and derive the TypeScript type from the schema, not from a parallel hand written interface, so type and check cannot drift.

  1. Wrap your fetch calls in one function that parses the response with a schema.
  2. Parse messages received from other windows before using any field. Also check the sender origin against an allowlist.
  3. Parse anything read back from localStorage, since the sheet notes that malicious data can be loaded into storage too.
  4. Treat URL query parameters the same way.
  5. On failure, fail closed with a clear error, not a quiet default.

Lint rules that help

The same cheat sheet recommends linting with the typescript-eslint recommended sets plus no-eval, no-implied-eval and no-new-func, so that code built from strings is blocked before it ships. It also says to keep dependencies updated so new rules apply, pin versions with a lockfile and review dependency changes.

Try it yourself

Click through it at your own pace, or open it full screen. Look for how a scan highlights unsafe sinks that a type checker will not.

Safeguard's free scan at gold.safeguard.sh/scan checks the dependencies in a TypeScript project.

Quick check

Does strict mode make my app secure?

It catches mistakes in your own code. It is not a trust boundary, because types vanish at runtime.

Why derive types from a schema?

So the validated shape and the compile time type are one definition, and cannot disagree.

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.