Emergency server help: get in touch

TypeScript Cheat Sheet: Types, Generics and tsconfig

A compact TypeScript 7.0 reference covering types, narrowing, generics, utility types and tsconfig, with examples checked by tsc 7.0.2.

Published 6 min read

Short answer: TypeScript adds static types to JavaScript: annotate with let port: number, describe objects with interface or type, combine types with unions (|) and narrow them with typeof or a kind field. Generics (<T>) and utility types such as Partial, Pick and Record remove repetition. The current release is TypeScript 7.0, a native compiler that is about ten times faster and uses strict by default.

The examples in this TypeScript cheat sheet were type-checked with TypeScript 7.0.2 (strict on) and the output run with Node.js 24.21.0 on 9 October 2026. Lines marked as errors were confirmed with // @ts-expect-error.

Basic types and annotations

SyntaxWhat it means
let host: string = "web01"Explicit annotation
let port = 443Inferred as number; annotate only where inference is not enough
const ids: number[] = [1, 2] · Array<string>Arrays, two equivalent spellings
const pair: [string, number] = ["db01", 3306]Tuple: fixed length and position types
let maybe: string | undefinedUnion: either type
unknownAny value, but you must narrow it before use. Prefer it to any
anyTurns type checking off for that value
voidFunction returns nothing useful
neverNever returns (always throws), or an impossible case
value as ServerType assertion: you tell the compiler, it does not check at run time
value!Non-null assertion: removes null and undefined. Use sparingly
let port = 443;
port = "80";        // error TS2322: Type 'string' is not assignable to type 'number'.

Interfaces and type aliases

interface Server {
  readonly id: number;        // cannot be reassigned
  name: string;
  ip: string;
  port?: number;              // optional: number | undefined
}

interface WebServer extends Server {
  vhosts: number;
}

type Status = "up" | "down" | "maint";         // literal union
type Point = { x: number; y: number };
type Tagged = Server & { tags: string[] };      // intersection

Both describe object shapes. Use interface for objects you may extend or merge, and type for unions, tuples, function types and computed types. A readonly property only stops reassignment through that type; it does not freeze the object.

Unions and narrowing

PatternExample
typeof checkif (typeof v === "number") return v.toFixed(1);
in checkif ("ip" in x) { ... }
instanceofif (e instanceof Error) console.error(e.message);
Truthiness and ?. · ??const len = maybe?.length ?? 0;
Discriminated uniontype Result = { ok: true; value: number } | { ok: false; error: string }
Type guard functionfunction isServer(x: unknown): x is Server { ... }

A shared literal property (kind below) lets the compiler narrow each case, and the never assignment fails to compile if someone adds a new shape without handling it:

type Shape = { kind: "circle"; r: number } | { kind: "square"; side: number };

function area(s: Shape): number {
  switch (s.kind) {
    case "circle": return Math.PI * s.r ** 2;
    case "square": return s.side ** 2;
    default: {
      const _exhaustive: never = s;
      return _exhaustive;
    }
  }
}

Functions and generics

SyntaxWhat it does
function connect(host: string, port = 22, ...opts: string[]): stringTyped parameters, default, rest and return type
const add = (a: number, b: number): number => a + bTyped arrow function
type Handler = (event: string) => voidFunction type
function first<T>(items: T[]): T | undefinedGeneric: the type flows from the argument
<T extends { length: number }>Constraint: T must have a length
<T, K extends keyof T>(obj: T, key: K): T[K]Typed property access; a wrong key is a compile error
function parse(v: string): number; function parse(v: number): string;Overload signatures, followed by one implementation
async function getJson<T>(url: string): Promise<T>Async functions return Promise<T>

Classes

abstract class Base {
  protected abstract kind: string;
  describe(): string { return `I am ${this.kind}`; }
}

class Db extends Base {
  protected kind = "db";
  #password = "x";                       // JavaScript private field (enforced at run time)
  static count = 0;

  constructor(public readonly name: string, private port: number = 3306) {
    super();                             // parameter properties create this.name and this.port
    Db.count++;
  }

  get dsn(): string { return `${this.name}:${this.port}`; }
  override describe(): string { return super.describe() + " " + this.dsn; }
}

private and protected are checked only at compile time; #field is private at run time too. Parameter properties (public name in the constructor) are not erasable syntax, so Node.js cannot run them directly from a .ts file (see the last section).

Utility types

TypeResult
Partial<Server>Every property optional (good for PATCH payloads)
Required<Server>Every property required
Readonly<Point>Every property readonly
Pick<Server, "name" | "ip">Only those properties
Omit<Server, "id">All except those properties
Record<Status, string[]>Object with exactly those keys
Exclude<Status, "maint"> · Extract<Status, "up">Remove from · keep from a union
NonNullable<string | null>Drop null and undefined
ReturnType<typeof fn> · Parameters<typeof fn>Return type · parameter tuple of a function
Awaited<Promise<number>>The resolved type: number

keyof, typeof, mapped and conditional types

SyntaxWhat it does
const d = { host: "localhost", port: 3306 } as constLiteral, readonly types for the whole object
typeof d · keyof typeof dType of a value · its keys as a union ("host" | "port")
Server["ip"]Indexed access: the type of one property
(typeof levels)[number]Union of an as const array’s items
{ [K in keyof T]: T[K] | null }Mapped type: transform every property
T extends string ? "yes" : "no"Conditional type
T extends (infer U)[] ? U : neverinfer: extract a type from inside another
`${"dev" | "prod"}-${"eu" | "us"}`Template literal type: four allowed strings
obj satisfies Record<string, `/${string}`>Check against a type but keep the narrower inferred type

tsconfig and the compiler

Command or optionWhat it does
npm install -D typescriptInstalls TypeScript 7 (the native, Go-based compiler) in the project
npx tsc --initWrite a starter tsconfig.json
npx tsc · npx tsc --noEmit · npx tsc -wBuild · type-check only · watch
"strict": trueAll strict checks. Default since TypeScript 6.0
"noUncheckedIndexedAccess": truerec[key] becomes T | undefined
"module": "nodenext"Correct ESM and CommonJS rules for Node.js
"rootDir": "./src" · "outDir": "./dist"Input and output folders. Set rootDir explicitly in 7.0
"types": ["node"]Global type packages. The default is now [], so list the ones you need
"erasableSyntaxOnly": trueReject enums, namespaces and parameter properties
--checkers 2 · --singleThreadedControl parallel type-checking (TypeScript 7)

TypeScript 7 adopts the 6.0 defaults and turns 6.0 deprecations into errors: target: es5, baseUrl, moduleResolution: node and the AMD, UMD and SystemJS module formats are gone. Tools that still need the old compiler API, such as typescript-eslint, can use the @typescript/typescript6 package side by side.

For server admins: config files and running .ts in Node.js

JSON from a file or an API is unknown until you check it. Validate the fields you need instead of casting blindly:

interface AppConfig { host: string; port: number; replicas?: string[] }

function loadConfig(text: string): AppConfig {
  const data: unknown = JSON.parse(text);
  if (typeof data !== "object" || data === null) throw new Error("config must be an object");
  const { host, port } = data as Record<string, unknown>;
  if (typeof host !== "string" || typeof port !== "number") {
    throw new Error("host and port are required");
  }
  return data as AppConfig;
}

Node.js 24 runs a .ts file directly (node check.ts) by stripping the types, without type-checking. It accepts only erasable syntax: an enum or a constructor parameter property makes it fail with a syntax error. Run npx tsc --noEmit in CI for the type check, and set erasableSyntaxOnly so the editor flags code that Node.js cannot strip. For large scripts, compile with tsc and run the JavaScript in dist/.

Official documentation (checked 9 October 2026): The TypeScript Handbook · Utility Types · TSConfig Reference · Announcing TypeScript 7.0 · Node.js v24: Modules: TypeScript

TypeScript Cheat Sheet at a glance

TypeScript Cheat Sheet – short answer
In short: A compact TypeScript 7.0 reference covering types, narrowing, generics, utility types and tsconfig, with examples checked by tsc 7.0.2.
TypeScript Cheat Sheet – what this guide covers
TypeScript Cheat Sheet: what this guide covers.

Related: JavaScript Cheat Sheet: Modern Syntax for Browser and Node · JSON Formatter and Validator · Regex Tester for JavaScript.

Reading a lot of our guides? Go ad-free with srvScripts Pro for $6 a month. It also pays for new guides. Cancel any time.

Share this guide

Free website test

Is your website set up right?

Check SSL, security headers, redirects, robots.txt, sitemap, llms.txt and security.txt in one test. It takes about 30 seconds.