TypeScript Cheat Sheet

Your pocket guide to TypeScript: types, narrowing, generics, and running .ts files in Node.js with the mental models to write, read, and review modern JavaScript. You can also download the information as a printable cheat sheet:

Free Bonus: TypeScript Cheat Sheet

Get the TypeScript Cheat Sheet (PDF), a printable reference to type annotations and inference, interfaces vs. type aliases, unions and narrowing, generics, utility types, unknown and satisfies, tsconfig essentials, and running TypeScript in Node.js:

TypeScript Cheat Sheet

Want a guided path instead of a reference? Start learning at realjs.com.

Types and Inference

  • Annotate boundaries, let inference do the rest
Language: TypeScript Filename: Annotate and Infer
let n = 42;            // type: number
const arr = [1, "a"];  // (string | number)[]
function add(a: number, b = 1) {
  return a + b;
}                      // returns: number
const u: { id: number; name?: string } =
  { id: 1 };
Language: TypeScript Filename: Interface or Type Alias
interface User { id: number; name: string }
interface Admin extends User {
  role: "admin";
}
type ID = string | number;
type Pt = { x: number } & { y: number };

Unions and Narrowing

Language: TypeScript Filename: Narrow With typeof and instanceof
function show(v: string | number | Date) {
  if (typeof v === "string") {
    return v.toUpperCase(); // v: string
  }
  if (v instanceof Date) {
    return v.toISOString(); // v: Date
  }
  return v.toFixed(1);      // v: number
}
Language: TypeScript Filename: Narrow With in
type Cat = { meow(): void };
type Dog = { bark(): void };
function speak(p: Cat | Dog) {
  if ("meow" in p) p.meow(); // p: Cat
  else p.bark();             // p: Dog
}
Language: TypeScript Filename: Discriminated Unions
type Result =
  | { ok: true; value: number }
  | { ok: false; error: string };
function unwrap(r: Result) {
  if (r.ok) return r.value; // r: ok true
  return r.error;           // r: ok false
}
Language: TypeScript Filename: Exhaustive Check With never
type S = { k: "a" } | { k: "b" };
function f(s: S) {
  switch (s.k) {
    case "a": return 1;
    case "b": return 2;
    default: {
      const x: never = s; // Error if a
      return x;           // case is missing
    }
  }
}

Literal Types

Language: TypeScript Filename: Literals and as const
const dir = "up";   // type: "up"
let dir2 = "up";    // type: string
type Dir = "up" | "down";
const cfg = {
  mode: "dev",
  ports: [80, 443],
} as const;
// type: { readonly mode: "dev";
//   readonly ports: readonly [80, 443] }
cfg.mode = "prod";  // Error: read-only

Generics

  • A generic is a type-level function parameter
Language: TypeScript Filename: Generic Functions
function first<T>(xs: T[]) {
  return xs[0];
}
first([1, 2]);   // returns: number
first<string>([]);  // undefined
Language: TypeScript Filename: Constrain With extends
function len<T extends { length: number }>(
  x: T,
) {
  return x.length;
}
len("abc");           // 3
len([1, 2]);          // 2
len(5);               // Error: no length

Utility Types

Language: TypeScript Filename: Reshape an Existing Type
interface User {
  id: number;
  name: string;
  email?: string;
}
type A = Partial<User>;  // All optional
type B = Required<User>; // All required
type C = Pick<User, "id">;
type D = Omit<User, "email">;
type E = Readonly<User>;
type F = Record<"a" | "b", number>;
// F: { a: number; b: number }
Language: TypeScript Filename: ReturnType and typeof
function mk() {
  return { id: 1, tags: ["a"] };
}
type M = ReturnType<typeof mk>;
// type: { id: number; tags: string[] }

unknown, any, satisfies

  • unknown forces a check before use, any switches checking off
  • satisfies validates a value and keeps its narrow type
Language: TypeScript Filename: Narrow unknown
function parse(j: string): unknown {
  return JSON.parse(j);
}
const data = parse('{"a":1}');
data.a;               // Error: unknown
if (
  typeof data === "object" &&
  data !== null &&
  "a" in data
) {
  console.log(data.a); // 1
}
Language: TypeScript Filename: Check With satisfies
type Pal = Record<string, string | number[]>;
const palette = {
  red: [255, 0, 0],
  green: "#0f0",
} satisfies Pal;
palette.red;          // type: number[]
palette.green;        // type: string

tsconfig Essentials

  • noEmit: check types only, Node.js runs the .ts
  • allowImportingTsExtensions allows ./a.ts imports
  • erasableSyntaxOnly rejects enums, namespaces, parameter properties
  • verbatimModuleSyntax demands import type for types
Language: JSON Filename: Settings for Node.js
{
  "compilerOptions": {
    "module": "nodenext",
    "moduleResolution": "nodenext",
    "strict": true,
    "noEmit": true,
    "allowImportingTsExtensions": true,
    "erasableSyntaxOnly": true,
    "verbatimModuleSyntax": true
  }
}

Run TypeScript in Node.js

  • Node 26 strips types by default, no flag
  • It does no type checking and ignores tsconfig.json
  • Imports need the .ts extension
  • .tsx and node_modules are unsupported
Language: Shell Filename: Run and Type-Check
$ node app.ts
$ npx tsc --noEmit
Language: TypeScript Filename: Imports Must Say type
import { greet, type User }
  from "./user.ts";
Language: TypeScript Filename: Not Supported by Stripping
enum Color { Red }          // enum
class P { constructor(public x: number) {} }
namespace N { export const a = 1 }
// Node: ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX
Language: TypeScript Filename: Use Erasable Alternatives
const Color = { Red: 0, Green: 1 } as const;
type Col =
  (typeof Color)[keyof typeof Color];
// type Col: 0 | 1
class P {
  x: number;
  constructor(x: number) { this.x = x; }
}

You can download this information as a printable cheat sheet:

Free Bonus: TypeScript Cheat Sheet

Get the TypeScript Cheat Sheet (PDF), a printable reference to type annotations and inference, interfaces vs. type aliases, unions and narrowing, generics, utility types, unknown and satisfies, tsconfig essentials, and running TypeScript in Node.js:

TypeScript Cheat Sheet