Skip to content

TypeScript / Node.js — Basics

  • V8 + libuv + Node bindings. JS single-threaded, I/O via libuv thread pool (default 4, UV_THREADPOOL_SIZE).
  • libuv uses epoll / kqueue / IOCP for network. Thread pool for file + DNS.
  1. timerssetTimeout/setInterval
  2. pending callbacks — deferred I/O
  3. idle/prepare — internal
  4. poll — fetch I/O events
  5. checksetImmediate
  6. closesocket.on('close')

Microtasks (process.nextTick, Promise .then) drain between phases. nextTick before Promises. Recursive nextTick starves I/O.

4 types: Readable, Writable, Duplex, Transform. Always use pipeline() (handles errors). Modes: flowing vs paused.

  • Structural typing (shape match).
  • any disables checks. unknown requires narrowing. never = impossible.
  • type = unions/intersections/mapped/conditional. interface = extensible via merging.
  • Narrow via typeof, instanceof, in, type guards (x is Foo), discriminated unions.
  • Utility: Partial, Required, Readonly, Pick, Omit, Record, Exclude, Extract, ReturnType, Parameters, Awaited.
  • Generics with extends constraints. Conditional T extends U ? X : Y. infer extracts.
  • Mapped: { [K in keyof T]: ... }.
  • tsconfig: strict, noUncheckedIndexedAccess, target, module, moduleResolution: NodeNext.
  • async returns Promise. await suspends.
  • Promise.all (fail-fast), allSettled, race, any.
  • Don’t await in loop for independent items — Promise.all(arr.map(...)).
  • Unhandled rejection crashes Node 16+.
  • CJS (require) vs ESM (import). ESM async, no __dirname default.
  • package.json "type": "module" switches default.
  • npm / pnpm / yarn. npm ci uses lockfile exact.
  • Semver: ^1.2.3 minor+patch, ~1.2.3 patch only.