Setup#

TypeScript is JavaScript plus a compile step and a type checker. Setup is JavaScript setup (Node, package manager) plus the TypeScript compiler (tsc), a tsconfig.json, and a @types/* story for any untyped dependencies.

For the JavaScript runtime install (Node, version managers, package managers), see Setup. This page covers the TypeScript-specific layers on top.

Install#

1. Install Node and a package manager. See Setup.

2. Add TypeScript as a dev dependency.

$ pnpm add -D typescript @types/node
$ pnpm exec tsc --init             # writes tsconfig.json

3. Verify.

$ pnpm exec tsc --version

Setup project#

1. Bootstrap.

$ mkdir my-tool && cd my-tool
$ pnpm init
$ pnpm add -D typescript @types/node tsx vitest
$ pnpm exec tsc --init --target ES2022 --module ESNext \
    --moduleResolution Bundler --strict

2. Wire the package scripts.

{
  "type": "module",
  "scripts": {
    "build": "tsc",
    "dev":   "tsx watch src/index.ts",
    "test":  "vitest"
  }
}

3. Lay out the source.

my-tool/
├── package.json
├── tsconfig.json
├── src/
│   ├── index.ts
│   └── types.ts
├── test/
│   └── index.test.ts
└── dist/                  # tsc output, gitignored

4. Run.

$ pnpm dev                 # tsx watches and runs
$ pnpm test
$ pnpm build               # writes dist/

Strict#

Turn on strict in tsconfig.json. Strict mode catches the errors you want caught.

{
  "compilerOptions": {
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "exactOptionalPropertyTypes": true,
    "noImplicitOverride": true
  }
}

Going lax later is cheap; going strict later means fixing every deferred any first.

Common Tasks#

Add type definitions for an untyped package.

$ pnpm add -D @types/<package-name>
# or write your own at src/types/<package>.d.ts

Run TypeScript directly without a build step.

$ pnpm exec tsx script.ts
$ pnpm dlx tsx script.ts      # ephemeral, no install

Type-check without emitting JS.

$ pnpm exec tsc --noEmit

Generate ``.d.ts`` files alongside ``.js``.

{ "compilerOptions": { "declaration": true, "declarationMap": true } }

References#