Reference · tooling & ecosystem

Tooling & ecosystem — decoder

The three things around the type language: how TS describes code it can't see, how it emits and finds modules, and where the compiler itself is going.

declare & .ts vs .d.ts (5.1)

thingmeansemits JS?
declareambient: "this exists at runtime, here's its type"no
.tsreal code + typesyes → .js
.d.tsdeclarations only — pure typesno — it is the types
Maxim: no body, no = → ambient. declare promises a value already exists and emits nothing. A .d.ts is a whole file of such declarations — the type-only shadow of JS that runs elsewhere (generated by tsc, or shipped as @types/*).
declare const VERSION: string;                 // global value, type only, no emit
declare function gtag(cmd: string): void;       // body-less — runtime supplies it

// math-utils.d.ts — describes an untyped JS library (declare implied in a .d.ts)
export function clamp(n: number, lo: number, hi: number): number;
export interface Range { min: number; max: number; }

module vs moduleResolution (5.2)

optionquestionexample values
moduleemit: what import/export syntax is written out?esnext, commonjs, nodenext
moduleResolutionfind: how is a specifier resolved to a file?bundler, node16, nodenext
Maxim: module = emit · moduleResolution = find. One shapes the output syntax; the other shapes the lookup during checking and never appears in the output. Pick a matched pair (e.g. both nodenext) so emit and resolution agree.
{
  "compilerOptions": {
    "module": "nodenext",            // EMIT: ESM or CJS, per package.json "type"
    "moduleResolution": "nodenext",  // FIND: Node rules — read "exports", check extensions
    "target": "es2022"             // (separate: which JS features to down-level)
  }
}

package.json is the third party both consult:

fieldeffect
"type": "module"marks files as ESM → under nodenext the emit keeps import/export
"exports"declares which files are importable & under which names → modern moduleResolution honors it

TypeScript 7.0 / the Go port (5.3)

changesstays the same
compiler reimplemented natively in Go (codename "Corsa"); ships as TS 7.0, 6.x continues meanwhilesyntax, type system, checking rules, .d.ts files, tsconfig — everything you read
Maxim: the compiler is ported, not the language. Reported gains: ~10x faster builds (≈9–13x across tested codebases), ~8x faster editor load, ~half the memory. Every type you can read today reads identically; only the speed changes.

The 3-second checks

  1. Body-less / no =? → ambient (declare / .d.ts); emits no JS.
  2. Output syntax wrong vs file not found? → emit problem = module; find problem = moduleResolution.
  3. Will the Go port change my types? → no — same language, just faster tooling.