← Learn Runs in your browser

Step 1 Types are checked, then erased

The compiler tsc does two separate jobs: it type-checks your code, and it emits JavaScript. Crucially, the emit step simply deletes all the type annotations, interfaces and generics — they leave no trace at runtime. Your running program is ordinary JavaScript; the types were only ever a compile-time conversation with the checker.

Pick a snippet — see what ships to the browser

TypeScript (what you write)
Emitted JavaScript (what runs)

Notice the right side has no types. Because types vanish, you cannot check a type with if at runtime — that is why typeof and other runtime checks still matter.

Step 2 Catching mistakes before the code runs

The payoff for annotating types is that the checker can prove whole classes of bugs cannot happen, and tell you at edit time instead of at 3am in production. It tracks the type of every value and complains when you use one incorrectly.

Click each line — would tsc accept it?

Green lines type-check; red lines are errors the compiler reports before the program ever runs. None of this changes the emitted JavaScript — it only decides whether compilation succeeds.

Step 3 Structural typing — shape is all that matters

Most languages use nominal typing: a value fits a type only if it was declared with that type's name. TypeScript is structural: a value fits if it has the right shape. If it has the required properties of the right types, it is assignable — no implements needed. (This is "duck typing", checked statically.)

Is each object assignable to Point?

interface Point { x: number; y: number }

Extra properties are fine for an existing value; missing or wrong-typed required properties are not. The name of the object's type is irrelevant — only its structure.

Step 4 Inference — types you do not have to write

You rarely annotate everything. TypeScript infers types from the right-hand side of assignments, from return statements, and from how values are used. Annotations are mostly for function boundaries and intent; inside, the checker figures it out.

What does TypeScript infer here?

Note const infers a narrower literal type than letconst s = "hi" is the literal type "hi", while let s = "hi" widens to string.

Step 5 Generics — types as parameters

A generic lets a function or type work over any type while keeping the relationship between input and output. Instead of returning any (which throws away safety), a type parameter <T> threads the caller's actual type through.

Instantiate function identity<T>(x: T): T

The compiler substitutes T with the type you pass, so the result type is exact — identity(42) returns number, not any. The same machinery powers Array<T>, Promise<T>, Map<K, V> and the rest.

Step 6 Glossary

TermIn one sentence
type erasureTypes are deleted during compile; nothing remains at runtime.
structural typingCompatibility is decided by shape, not by declared name.
inferenceThe compiler deduces types you did not write.
narrowingInside an if (typeof x === "string"), x is treated as a string.
unionstring | number — a value that is one of several types.
genericA type parameter <T> that keeps input/output types linked.
any vs unknownany disables checking; unknown forces you to narrow first.

The whole idea: annotate intent → the checker proves it → the types are erased → JavaScript runs. TypeScript adds zero runtime cost and zero runtime guarantees — its value is entirely in catching mistakes before you ship.

Send feedback

How this works

Stores only this report's id in your browser (localStorage) so a small note can pop up here once it ships. No account, nothing sent to us, no tracking. Clearing this site's data forgets it.

Changelog

What changed, and when. Newest first.

Loading…