Episode 1 — Fundamentals / 1.25 — TypeScript Essentials

1.25.c — Installing and Setting Up TypeScript

In one sentence: Getting started with TypeScript requires installing the compiler, creating a tsconfig.json, and optionally setting up ts-node for direct execution and VS Code for the best editing experience.

Navigation: ← 1.25 Overview · 1.25.d — Basic Types →


1. Prerequisites

Before installing TypeScript, ensure you have:

  • Node.js (v16 or later) — nodejs.org
  • npm (comes with Node) or pnpm / yarn
  • A terminal (Terminal on macOS, Command Prompt / PowerShell on Windows, or VS Code integrated terminal)
# Verify Node and npm are installed
node --version    # e.g., v20.11.0
npm --version     # e.g., 10.2.4

2. Installing TypeScript

Local install (recommended for projects)

Install TypeScript as a dev dependency so every team member uses the same version:

# Initialize a new project (if you haven't already)
npm init -y

# Install TypeScript locally
npm install -D typescript

Now you can run it with npx:

npx tsc --version   # e.g., Version 5.4.5

Global install (for quick experiments)

# Install globally — available everywhere
npm install -g typescript

# Now 'tsc' works without npx
tsc --version

Best practice: Use local installs for real projects (pinned version in package.json), global installs for quick one-off experiments.


3. Initializing a TypeScript project

The tsc --init command creates a tsconfig.json file with sensible defaults:

npx tsc --init

This generates a tsconfig.json with many options commented out. A minimal starting config:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "strict": true,
    "outDir": "./dist",
    "rootDir": "./src",
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}
OptionWhat it does
targetJavaScript version for the output (ES2020, ESNext, etc.)
moduleModule system (commonjs for Node, ESNext for bundlers)
strictEnables all strict type-checking options (always recommended)
outDirWhere compiled .js files go
rootDirWhere your .ts source files live
esModuleInteropFixes import x from 'module' compatibility
skipLibCheckSkips type-checking .d.ts files (faster builds)
include / excludeWhich files to compile / ignore

See 1.25.j — tsconfig Explained for a deep dive on every option.


4. Compiling TypeScript

Compile a single file

npx tsc hello.ts       # Produces hello.js in the same directory

Compile a project (using tsconfig.json)

npx tsc                # Compiles all files matching 'include' in tsconfig.json

Watch mode — auto-recompile on save

npx tsc --watch        # or: npx tsc -w

Watch mode monitors your files and recompiles automatically whenever you save. Terminal output shows errors in real time.

Type-check only (no output)

npx tsc --noEmit       # Checks types but does not produce .js files

This is useful when a bundler (Vite, webpack) handles the actual compilation and you only want TypeScript for type checking.


5. Using ts-node for direct execution

Normally you must compile then run: tsc && node dist/app.js. ts-node combines both steps:

# Install ts-node
npm install -D ts-node

# Run a TypeScript file directly
npx ts-node src/app.ts

How it works: ts-node compiles your TypeScript in memory and runs the resulting JavaScript — no separate compile step, no output files.

tsx — the modern alternative

tsx (not to be confused with .tsx React files) is a faster alternative to ts-node:

# Install tsx
npm install -D tsx

# Run a TypeScript file
npx tsx src/app.ts

# Watch mode (auto-restart on changes)
npx tsx watch src/app.ts

tsx vs ts-node:

Featurets-nodetsx
SpeedSlower (full type checking)Faster (strips types only, no type checking)
ESM supportRequires configurationWorks out of the box
SetupMay need extra flagsZero config
Type checkingYes (by default)No (use tsc --noEmit separately)

6. IDE setup — VS Code

VS Code has built-in TypeScript support — no extensions needed for core functionality:

  • Syntax highlighting for .ts and .tsx files
  • IntelliSense — autocomplete powered by TypeScript's type system
  • Hover information — hover any variable to see its type
  • Go to Definition — Ctrl/Cmd+Click on any symbol
  • Error highlighting — red squiggles for type errors inline
  • Rename symbol — F2 to rename across all files
  • Auto-imports — VS Code suggests imports as you type

Recommended VS Code settings for TypeScript

Add to your .vscode/settings.json:

{
  "typescript.preferences.importModuleSpecifier": "relative",
  "typescript.suggest.autoImports": true,
  "typescript.updateImportsOnFileMove.enabled": "always",
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.organizeImports": "explicit"
  }
}

Recommended extensions

ExtensionPurpose
Error LensShows errors inline next to the offending line
Pretty TypeScript ErrorsFormats complex TS errors to be more readable
ESLintLinting integration (see 1.25.l)
PrettierCode formatting

7. Adding TypeScript to an existing JS project

You do not need to convert everything at once. TypeScript supports incremental adoption:

Step-by-step migration

# 1. Install TypeScript
npm install -D typescript

# 2. Create tsconfig.json with loose settings
npx tsc --init
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "strict": false,
    "allowJs": true,
    "checkJs": false,
    "outDir": "./dist",
    "rootDir": "./src",
    "esModuleInterop": true,
    "skipLibCheck": true
  },
  "include": ["src/**/*"]
}

Key settings for migration:

  • allowJs: true — lets .js files coexist with .ts files
  • strict: false — starts with loose checking (tighten later)
  • checkJs: false — does not type-check .js files (opt-in per file with // @ts-check)
# 3. Rename files one at a time: .js → .ts
# 4. Fix type errors in each file
# 5. Gradually enable strict options
# 6. Eventually: strict: true, allowJs: false

Per-file opt-in for JS files

Add // @ts-check at the top of a .js file to get TypeScript checking without renaming:

// @ts-check

/** @type {string} */
let name = "Alice";
name = 42;  // Error: Type 'number' is not assignable to type 'string'

8. @types/* packages — type definitions for JS libraries

Many popular JavaScript libraries do not ship their own types. The DefinitelyTyped community project provides type definitions as @types/* packages:

# Example: adding types for Express
npm install express
npm install -D @types/express

# Example: adding types for lodash
npm install lodash
npm install -D @types/lodash

# Example: adding types for Node.js built-in modules
npm install -D @types/node

How it works:

  • @types/express provides .d.ts declaration files that describe Express's API
  • TypeScript automatically picks them up from node_modules/@types/
  • You get full autocomplete and type checking for the library

When you DON'T need @types/*:

  • Libraries written in TypeScript already include types (e.g., zod, prisma, axios)
  • Check the library's package.json for a "types" or "typings" field
# Check if a library ships its own types
npm info axios types   # Shows: "./index.d.ts" — types included!
npm info express types # Shows: nothing — need @types/express

9. Real setup walkthrough: from empty folder to running TS

# 1. Create project folder
mkdir my-ts-project && cd my-ts-project

# 2. Initialize npm
npm init -y

# 3. Install TypeScript and ts-node (or tsx)
npm install -D typescript tsx @types/node

# 4. Create tsconfig.json
npx tsc --init

# 5. Create source directory
mkdir src

# 6. Create your first TypeScript file

Create src/index.ts:

interface Greeting {
  message: string;
  recipient: string;
}

function createGreeting(name: string): Greeting {
  return {
    message: `Hello, ${name}!`,
    recipient: name,
  };
}

const greeting = createGreeting("World");
console.log(greeting.message);  // "Hello, World!"
# 7. Run directly with tsx
npx tsx src/index.ts
# Output: Hello, World!

# 8. Or compile and run separately
npx tsc
node dist/index.js
# Output: Hello, World!

# 9. Add scripts to package.json

Add to package.json:

{
  "scripts": {
    "dev": "tsx watch src/index.ts",
    "build": "tsc",
    "start": "node dist/index.js",
    "typecheck": "tsc --noEmit"
  }
}
# 10. Use the scripts
npm run dev        # Development with auto-restart
npm run build      # Compile to JavaScript
npm start          # Run compiled code
npm run typecheck  # Type-check only

10. Project structure conventions

A typical TypeScript project layout:

my-ts-project/
  src/               ← TypeScript source files
    index.ts
    utils/
      helpers.ts
    types/
      index.ts       ← shared type definitions
  dist/              ← compiled JavaScript (gitignored)
  node_modules/
  package.json
  tsconfig.json
  .gitignore         ← include: node_modules/, dist/

Key takeaways

  1. Install TypeScript locally with npm install -D typescript; use npx tsc to compile.
  2. npx tsc --init creates tsconfig.json — your project's TypeScript configuration.
  3. Watch mode (tsc --watch) recompiles on every save.
  4. tsx or ts-node lets you run .ts files directly without a separate compile step.
  5. VS Code has built-in TypeScript support — no extensions needed for core features.
  6. Migrate JS projects gradually: allowJs: true, rename files one at a time, tighten strict over time.
  7. Use @types/* packages for type definitions of JavaScript libraries that do not ship their own.

Explain-It Challenge

Explain without notes:

  1. What is the difference between npm install -D typescript and npm install -g typescript?
  2. Why might you use tsc --noEmit instead of tsc?
  3. How do @types/* packages work, and when do you NOT need them?

Navigation: ← 1.25 Overview · 1.25.d — Basic Types →