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)
| thing | means | emits JS? |
| declare | ambient: "this exists at runtime, here's its type" | no |
| .ts | real code + types | yes → .js |
| .d.ts | declarations only — pure types | no — 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)
| option | question | example values |
| module | emit: what import/export syntax is written out? | esnext, commonjs, nodenext |
| moduleResolution | find: 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:
| field | effect |
| "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)
| changes | stays the same |
| compiler reimplemented natively in Go (codename "Corsa"); ships as TS 7.0, 6.x continues meanwhile | syntax, 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
- Body-less / no
=? → ambient (declare / .d.ts); emits no JS.
- Output syntax wrong vs file not found? → emit problem =
module; find problem = moduleResolution.
- Will the Go port change my types? → no — same language, just faster tooling.