What is TypeScript?

JavaScript with an extra layer that checks the *shape* of your data before your code ever runs.

What is it?

Picture a normal JavaScript function that adds two numbers:

function add(a, b) { return a + b; }

Nothing stops you from calling add("5", 10) by mistake. JavaScript won't complain — it will just quietly turn "5" + 10 into the string "510", and you won't find out something went wrong until the bug shows up somewhere far downstream, maybe in production, maybe hours later.

Now imagine a tool that reads your code before you ever run it, and says: "Hold on — add expects two numbers, but you're passing a string here. This is almost certainly a mistake." That's the core idea. A layer sits on top of JavaScript, lets you describe what kind of value each variable, parameter, and return value is supposed to be, and then checks that every part of your code is consistent with those descriptions — catching an entire category of bugs while you're still typing, instead of after the program runs. This is called static typing — "static" because the checking happens by reading the code, not by running it.

That extra layer is TypeScript. It's not a separate language that replaces JavaScript — it's JavaScript plus optional type annotations. Because browsers and Node.js don't understand those annotations, a TypeScript file (.ts) is run through a compiler that strips the types back out and produces plain, ordinary JavaScript (.js) — the exact same JavaScript you'd have written by hand, just checked for mistakes first.

Explain like I'm 10

It's like a spell-checker for your code's data. You can still write whatever you want, but before you hit send, it underlines the parts that don't make sense — like passing a phone number where an email address was expected — so you can fix it before anyone else sees it.

Examples

A mistake JavaScript won't catch

// plain JavaScript
function add(a, b) {
  return a + b;
}

add("5", 10); // returns "510", no error, no warning

JavaScript happily runs this. The bug is silent — it just produces a weird result and moves on.

The same mistake in TypeScript

// TypeScript
function add(a: number, b: number): number {
  return a + b;
}

add("5", 10);
// Error: Argument of type 'string' is not assignable
// to parameter of type 'number'.

The : number after each parameter is a type annotation. TypeScript reads this before running anything and flags the call as invalid — right in your editor, often as you type.

How it works

TypeScript code lives in .ts files. A program called the TypeScript compiler (tsc) reads those files, checks every type annotation against how the values are actually used, and reports any mismatches as errors.

If there are no errors (or you choose to ignore them), the compiler then strips all the type annotations out and writes plain .js files — the kind any browser or Node.js can run directly. The types themselves never exist at runtime; they're purely a tool for catching mistakes ahead of time. This is why people describe TypeScript as a "compile-time" layer: it does its job before the program runs, then gets out of the way.

you write:      app.ts (JavaScript + type annotations)
                     ↓
TypeScript compiler checks types, reports errors
                     ↓
                strips the types out
                     ↓
you get:        app.js (plain JavaScript)
                     ↓
              runs in browser / Node.js

Why does it exist?

As JavaScript projects grow from a few hundred lines to hundreds of thousands, small mistakes — passing the wrong kind of value, misspelling a property name, forgetting that a value might be missing — become far more common and far more expensive to track down. JavaScript itself has no way to describe what a function or variable expects, so those mistakes only surface when the code actually runs, sometimes in front of real users.

TypeScript was created (by Microsoft, first released in 2012) to let large codebases describe those expectations explicitly, so tools and compilers can catch violations immediately, instead of relying entirely on tests and manual review to find them.

When to use it

Reach for TypeScript on any project that's going to grow, be touched by more than one person, or live long enough that "what shape of data does this function expect?" becomes hard to remember. It pays off especially in teams, libraries other code depends on, and codebases where refactoring needs to feel safe.

When not to use it

For a five-minute throwaway script, a quick experiment, or a tiny snippet where adding type annotations would take longer than writing the code itself, plain JavaScript is often simpler and faster. TypeScript also adds a build step — if that overhead genuinely doesn't pay for itself, it's fine to skip it.

Common mistakes

  • Thinking TypeScript is a completely different language from JavaScript — it's JavaScript with an added layer of type annotations that gets removed before the code runs.

  • Believing TypeScript makes code run faster. It doesn't change runtime performance at all — it only catches mistakes earlier, before the code runs.

  • Assuming type errors will stop the program from ever running. By default the compiler still produces JavaScript output even with errors, unless you configure it to refuse.

Practice exercises

  1. Easy:

    Write a JavaScript function multiply(a, b) with no types, then rewrite it in TypeScript adding : number annotations to both parameters and the return value.

  2. Medium:

    In your rewritten TypeScript function, try calling it with a string argument and read the exact error TypeScript reports. Write down, in your own words, what the error is telling you.

  3. Hard:

    Explain, without using the word "TypeScript", what problem static typing solves that plain JavaScript can't — as if explaining it to someone who has never programmed.

Interview questions

What is TypeScript, in relation to JavaScript?

A superset of JavaScript that adds optional static type annotations, checked by a compiler before the code runs, which then strips those annotations and outputs plain JavaScript.

Does TypeScript code run directly in the browser?

No. It's compiled to plain JavaScript first; browsers and Node.js only ever run the resulting JavaScript, never the TypeScript source directly.

What is static typing, and what problem does it solve?

Checking that values match their expected types by reading the code, before it runs. It catches a whole class of mistakes — like passing the wrong kind of value to a function — at compile time instead of at runtime.

Why is TypeScript called a *superset* of JavaScript rather than a separate language?

Every valid JavaScript program is already valid TypeScript — TypeScript only adds optional syntax (type annotations) on top. It doesn't remove or replace any JavaScript feature, it just layers extra checking on top of the language you already know.

Does using TypeScript make your code run faster at runtime?

No. TypeScript has zero effect on runtime performance — by the time the code runs, it's plain JavaScript with all type information stripped out. TypeScript only helps you catch mistakes earlier, before that JavaScript is even produced.

If your TypeScript file has type errors, does `tsc` still produce a `.js` file by default?

Yes. By default the compiler reports the errors but still emits JavaScript output — it doesn't refuse to compile. You have to explicitly opt in (for example, a noEmitOnError setting) to make errors block the build.

What are the TypeScript compiler's two main jobs?

First, it reads every type annotation and checks it against how values are actually used, reporting mismatches as errors. Second, regardless of whether errors were found, it strips all the type annotations out and writes plain JavaScript that any browser or Node.js can run.

Why is TypeScript's checking described as happening "at compile time" instead of "at runtime"?

The compiler finds mismatches purely by reading your code's structure — it never actually executes the call to discover the problem. That analysis-without-running is what "compile time" means, as opposed to a bug that only surfaces once the program is actually executing.

Since type annotations are erased before the code runs, can you check a variable's declared TypeScript type at runtime with `typeof`?

No — typeof at runtime only tells you the actual JavaScript value's type ("string", "number", and so on), because the TypeScript annotation no longer exists by then. The declared type is a compile-time-only concept; it has no runtime representation to inspect.

What is *type erasure*, in the context of TypeScript?

The process by which the compiler removes every type annotation, interface, and type alias from the code before producing JavaScript output. It's why TypeScript's types can never be inspected or relied on at runtime — they simply don't exist anymore by then.

A function like `function add(a, b) { return a + b; }` in plain JavaScript accepts `add("5", 10)` without complaint. What does it actually do, and why doesn't TypeScript's equivalent have the same problem?

Plain JavaScript coerces the string, producing "510", silently. The TypeScript version, function add(a: number, b: number): number, has type annotations the compiler checks the call against — it flags the string argument as an error before the code ever runs, rather than letting it execute and produce a wrong result.

Is it accurate to say TypeScript is a completely different language from JavaScript that has to be learned from scratch?

No — this is a common beginner misconception. TypeScript is JavaScript with an added, optional layer of type annotations. Anyone who knows JavaScript already knows the vast majority of TypeScript; the new material is the type syntax on top.

Why might static typing catch bugs "while you're still typing," rather than only when you run `tsc` from the command line?

Editors integrate the TypeScript compiler to run its type-checking continuously in the background, underlining mismatches as you write code — you don't have to finish the file and run a separate command to see the error.

Why does static typing tend to matter more as a JavaScript project grows from a few hundred lines to hundreds of thousands?

In a small script, it's easy to hold every function's expected inputs in your head. As a codebase grows and is touched by more people, that mental bookkeeping becomes unreliable — mistakes like passing the wrong shape of value become both more likely and more expensive to trace back, which is exactly what explicit, compiler-checked types are designed to prevent.

For a five-minute throwaway script, why might plain JavaScript be a better choice than TypeScript?

TypeScript adds a build step (compiling before you can run the code) and requires writing type annotations. For code you'll run once and discard, that overhead can cost more time than it saves, since there's no future maintenance or team of collaborators for the type safety to protect.

A teammate suggests annotating every single variable in a codebase explicitly, even ones like `let count = 0`. Is that necessary?

No — TypeScript infers the type of a variable from its initializer, so let count = 0 is already understood as number without an annotation. Explicit annotations are most valuable where the type isn't obvious from context, such as function parameters.