Getting Started with TypeScript

This section documents the current TypeScript release line as published at the official TypeScript documentation, which is the reference these pages are written and verified against. No specific patch version is pinned.

This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production, since TypeScript iterates quickly.

This section’s bibliography lists the reference material consulted while preparing these pages.

TypeScript is JavaScript with a static type layer that the compiler checks and then throws away. You write .ts, tsc verifies the types and emits ordinary .js — nothing about the running program changes. If you have five minutes, read TypeScript in 5 minutes first; this page is the hands-on version.

An erasable typed superset of JavaScript

Every valid JavaScript file is already a valid TypeScript file. TypeScript only adds annotations, and those annotations exist only at compile time: they are checked, then stripped. There are no runtime types, no reflection, and no runtime cost.

function greet(user: { name: string; age: number }): string {
  return `Hello, ${user.name} (${user.age})`;
}

const alice = { name: "Alice", age: 30 };
console.log(greet(alice));

Compiled with tsc (targeting a modern runtime), the emitted JavaScript is what you would have written by hand — the shape at runtime is identical:

function greet(user) {
    return `Hello, ${user.name} (${user.age})`;
}
const alice = { name: "Alice", age: 30 };
console.log(greet(alice));

Type-checking and code generation are independent passes. By default a type error is reported but does not stop the emit:

let count: number = 1;
count = "two";
$ npx tsc bad.ts
bad.ts:2:1 - error TS2322: Type 'string' is not assignable to type 'number'.

2 count = "two";
  ~~~~~

Found 1 error in bad.ts:2

bad.js is still written, containing count = "two". Set noEmitOnError in tsconfig.json (or pass --noEmitOnError) when you want a failed check to suppress output — the usual choice for CI. See tsconfig and Compiler Options for the switches that shape the emit.

Install and first compile

Install TypeScript as a per-project dev dependency so every checkout builds against a known version:

npm i -D typescript          # local dev dependency
npx tsc --version

npx tsc --init               # writes tsconfig.json with strict defaults
npx tsc                      # compile every file the tsconfig includes
npx tsc --watch              # recompile on save (alias: -w)
npx tsc hello.ts             # one-off: compile a single file, ignoring tsconfig

The download page covers global installs, other package managers, and the nightly build.

Create hello.ts:

const who: string = process.argv[2] ?? "world";
console.log(`Hello, ${who}!`);

Compile it and run the output with Node:

npx tsc hello.ts        # produces hello.js
node hello.js TypeScript
# -> Hello, TypeScript!

Running .ts directly with type-stripping runners

Several tools run a .ts file without a separate build step by erasing the types in memory:

npx tsx hello.ts                          # tsx
npx ts-node hello.ts                      # ts-node
node --experimental-strip-types hello.ts  # Node (built-in; unflagged in current releases)
deno run hello.ts                         # Deno -- TS support is native
bun hello.ts                              # Bun -- TS support is native

Caveat: these run but do not type-check. The count = "two" program above executes to completion under every one of them. Keep npx tsc --noEmit, your editor, or a CI step as the real type gate. Node’s built-in stripping is the strictest — it rejects TypeScript syntax that emits code (enum, namespace, parameter properties), so it only accepts genuinely erasable syntax.

The Playground and your editor

The TypeScript Playground is the compiler running in your browser: paste TypeScript and see the emitted JavaScript, the errors, the generated .d.ts, and every compiler option as a toggle. Each session is a shareable URL, which is why most examples in the official docs link straight into it.

Locally, VS Code bundles the TypeScript language service, so hover, go-to-definition, autocomplete, rename, and inline errors work in .ts (and .js) files with no extension to install; other editors reach the same service over the Language Server Protocol. Use your editor to interrogate the type system — hover a value to see what TypeScript inferred, rather than guessing:

const ids = [1, 2, 3].map((n) => n.toString());
//    ^? const ids: string[]
// Hover `ids` in the editor, or use the `//   ^?` twoslash query in the Playground.

What TypeScript is not

  • Not a runtime. There is no "TypeScript engine". The output is plain JavaScript for Node, Deno, Bun, or a browser. tsc itself is TypeScript compiled to JavaScript.

  • Not a linter. It checks types, not style or best practices. Run ESLint alongside it for rules like "unused variables are an error" or "prefer `const`".

  • Not a rewrite of your logic. Erasing the annotations from a .ts file gives back working .js. The few constructs that do emit extra code (enum, namespace, constructor parameter properties, legacy experimentalDecorators) are opt-in and avoidable.

  • Not slower JavaScript. Types cost compile time only. The shipped code carries zero type-related overhead — nothing is added, checked, or reflected at runtime.

The compile pipeline

flowchart LR A[".ts source"] --> B["parse
(build AST)"] B --> C["bind
(symbols and scopes)"] C --> D["type-check
(report errors)"] D --> E["transform
(strip types, downlevel syntax)"] E --> F["emit"] F --> G[".js"] F --> H[".d.ts — with declaration"] F --> I[".js.map — with sourceMap"] D -. "errors are reported but do NOT stop emit
unless noEmitOnError is set" .-> E

The type-check and transform stages share the parsed AST but are otherwise decoupled: by default tsc prints every error and still writes the .js. noEmitOnError is what ties a clean type-check to a successful build. Declaration files (.d.ts) and source maps (.js.map) are produced by the same emit step when declaration and sourceMap are enabled.

Where to go next

  • The Type System — annotations, inference, unions, narrowing, generics, and the structural rules behind the errors above.

  • tsconfig and Compiler Options — strict, target, module, noEmitOnError, and the rest of `tsc --init’s output.

  • JavaScript Reference — the language TypeScript compiles down to.

  • The Basics in the official handbook picks up exactly where this page stops.