learn
TypeScript

How TypeScript works

Compile time versus runtime, checking versus emit, and how people run it.

TypeScript does its work before your code ever runs, then gets out of the way. Two distinctions carry every interview answer: checking is not emit, and compile time is not runtime.

Visual

TypeScript pipeline
BrowserAPIRealtimeCacheDatabaseShareddurableephemeral

Compile time versus runtime

Checking asks "could this be wrong?" Emit asks "what JavaScript should ship?" They are independent: even with errors, the compiler still emits (try it below — the runner tells you plainly when it does). At runtime no type information remains, so no instanceof trick can recover an interface. If you need safety from real data, you validate at runtime; types only describe what you claimed.

Structural typing fits here too: two types with the same shape are compatible, whatever their names. The snippet below passes because coords has everything Point asks for — no declaration of intent.

interface Point {
  x: number;
  y: number;
}
const coords = { x: 1, y: 2 };
const spot: Point = coords;
console.log(spot.x + spot.y);

How people run TypeScript

Most projects compile with tsc or let a bundler strip types during the build. For running directly: Node.js executes TypeScript files itself since v22.6.0, enabled by default since v22.18.0 and v23.6.0, and stable since v24.12.0 — but it only strips types, never checks them (Node.js TypeScript docs). Community runners like tsx go further with full transformation. And since July 2026, the tsc binary in the typescript package is the native Go compiler; programmatic users stay on the 6.x line (see the 7.0 announcement).

Try it

Errors do not stop emit

Checked with TypeScript 6.0.3, strict mode

typescriptTab moves to the next control
function cartTotal(prices: number[]): number {
let total = 0;
for (const price of prices) {
  total = total + price;
}
return total;
}
console.log("total: " + cartTotal([12, 8, 20]));
const typo: number = "12";
console.log("total: " + cartTotal([typo]));

Compiler not loaded. Check or Run loads it here (about 9 MB) — nothing downloads until you do.

Runner helpers

sleep(ms) waits; fakeFetch(url) returns deterministic sample data. TypeScript is stripped before running; imports and exports are not available in the sandbox.

Run it, then read both tabs: the Types tab reports the mismatch while the Output tab still prints. Change "12" to 12 and watch the Types tab go quiet. That split — noisy at compile time, silent at runtime — is the mental model behind every page that follows.

Interview questions

How does the tsc compiler turn TypeScript into JavaScript?basic

You run tsc over your .ts files and it does two jobs: it checks your types against each other, then it strips the type syntax and emits plain .js. Modern syntax is downleveled to match your target, so optional chaining or classes still run on older runtimes. You configure the input, output folder, and language level in tsconfig.json, and the emitted files are what you actually deploy and run.

Interviewers also ask

  • What part of the output can you run in the browser?
What does it mean that TypeScript types are erasable?basic

It means every annotation, interface, and type alias is removed when the code is emitted — no trace remains at runtime. The emitted JavaScript behaves exactly as if you had written it by hand without types. You cannot inspect an interface in running code or branch on it, because it no longer exists. If you need a runtime check, you must write real JavaScript logic such as a typeof test or a validation function.

Interviewers also ask

  • Can you check an interface with an if statement at runtime?
Does TypeScript do any runtime type checking?intermediate

No, the compiler performs no runtime checking itself. Once your .ts is emitted to .js, all types are gone and execution follows normal JavaScript rules — a wrong-typed API response flows straight through. The safety comes entirely from the build-time check plus the runtime guards you write yourself. That is why teams pair TypeScript with small validators at program boundaries, where outside data enters typed code.

Interviewers also ask

  • Where should you put runtime checks in a typed app?
How can Node.js run .ts files directly with type stripping?basic

Recent Node versions can run .ts files by stripping the type syntax without doing any type checking, so development feels instant. The feature first appeared around v22.6.0, became enabled by default through the v22 and v23 line, and stabilized later — check your exact Node version before relying on it. Remember it only removes types: type errors still run, and syntax Node cannot strip cleanly needs a real build step.

Interviewers also ask

  • Does running a .ts file in Node prove its types are correct?
If tsc reports a type error, does it still emit JavaScript?intermediate

By default yes — checking and emitting are separate steps, so tsc prints the errors but still writes .js output unless you set noEmitOnError. That surprises beginners who expect errors to block the build. In practice you decide: leave the default for quick iteration, or enable noEmitOnError in CI so broken types cannot ship. Either way, fix the reported errors — the emitted code still runs as plain JavaScript.

Interviewers also ask

  • How would you block a deploy on type errors?
What tools besides tsc can compile TypeScript?intermediate

Many tools transpile TypeScript by stripping types without full checking: esbuild, swc, tsx, and bundlers built on them compile single files very fast. That speed is ideal for development and bundling, but none of them replaces tsc for correctness — they happily emit code with type errors. A common setup uses a fast transpiler to build and runs tsc --noEmit alongside it purely to check types.

Interviewers also ask

  • Why run tsc --noEmit next to a fast bundler?

References

Last verified: 2026-10-13.

On this page