Roadmap to a production type-checking compiler.
The destination is ambitious and explicit. The method is deliberately patient: protect the fast working transpiler, then add structural and semantic capability as complete vertical slices.
The external suite is now reconciled to 600/0/18 across 618 cases, the detailed compatibility matrix covers 33 areas, and three real package source distributions contributed nine classified probes. The next compiler campaign is therefore evidence-selected rather than speculative.
Harden the transpiler contract
Define supported syntax, modules, projects, diagnostics and output policy. Preserve runtime behavior, performance and controlled failure under every later checkpoint.
Build durable syntax structure
Add coherent nodes and stable source spans where binding and checking need identity, while retaining the proven source-edit emitter.
Introduce names, declarations and scopes
Model modules, functions, parameters and blocks correctly—including var, lexical declarations, shadowing, closures and merging rules.
Grow the type system vertically
Move from the first primitive literal check into literal, union, object, function and generic relationships with positive and negative diagnostics at every slice.
Unify program and module semantics
Give one program graph ownership of source identity, resolution, symbols, diagnostics and future incremental invalidation.
Broaden TypeScript compatibility
Add inference, narrowing, classes, overloads, advanced types, JSX typing, libraries, packages and configuration according to measured demand and evidence.
Production hardening
Validate real projects, memory, fuzzing, sanitizers, platforms, diagnostics, packaging, releases and eventually incremental/watch behavior.
Checkpoint path to the current CP75 pause baseline
Durable syntax identity complete
Structural nodes now retain stable IDs, parent relationships, exact token/byte spans and explicit recovery identity through checking and emission.
Deterministic recovery complete
Malformed EOF/delimiter paths resynchronize at declaration boundaries, retain following declarations and obey a configurable parser work ceiling.
First JS++ test integration complete
Six eligible outputs execute independently under Node and JS++, guarded by explicit expected values and anti-agreement classification. Normal compilation remains independent.
Declaration and scope slice complete
Arrow parameters/scopes, flat destructuring, class names, captures, shadowing and hoisted function identity now belong to the binder.
Bounded function signatures complete
Typed ordinary declarations now carry durable parameter/result signatures into argument, arity and annotated-return checking.
Core type algebra complete
Literal, normalized union, null and undefined types now have canonical identities and bounded assignability.
Bounded branch narrowing complete
Strict typeof and literal/nullish equality guards now create then-branch facts that restore at the lexical boundary.
Canonical object shapes established
The durable type store now interns structural object shapes and retains optional and readonly property metadata. Source-facing structural checks follow in CP20.
Bounded structural checking
Flat object annotations and literals now support named reads, required and optional assignment, and readonly write diagnostics. Nested/indexed shapes and freshness remain later work.
Nested structural checking
Nested shapes, chained reads and property-path diagnostics are complete. Extra source properties remain compatible by explicit structural policy.
Durable expression identity
Checked expression spans are interned into the compilation unit and retained through emission, establishing the migration seam for richer expression nodes.
Structured expression ownership
Retained expressions now carry explicit literal, identifier, unary, binary, call, property, object-literal and assignment structure with durable child identities. This is architecture, not a broader compatibility claim.
Reusable object declarations
Basic object aliases and interfaces now resolve to canonical shapes, including compatible interface merging and nested optional/readonly properties. Indexed/call signatures, inheritance, generics and classes remain later work.
Expression typing migration
The checker now walks the retained expression graph directly. The former significant-token compatibility view is gone, leaving one precedence parse and one durable semantic identity.
Canonical callable types
Function signatures are now canonical type identities shared by aliases, annotated variables and declarations, with explicit arity/rest metadata and a bounded variance policy. Callable-variable behavior follows in CP32.
Contextual callable expressions
Annotated callable variables now drive call checking and contextually type bounded arrow and function expressions, including their parameters and return values. The corpus is 539 cases at 515/0/24.
Whole-program callable checks
Callable argument and arity diagnostics now apply in standalone, branch and throw contexts as well as checked initializers. The corpus is 543 cases at 519/0/24.
Callable inference
Typed arrows and function expressions infer callable variable identities, while contextual optional, default and rest parameter forms share the canonical callable model. The corpus is 549 cases at 525/0/24.
Nested contextual callbacks
Call arguments own recursive expression subtrees, enabling contextual inline arrow and function callbacks without duplicate diagnostics. The corpus is 553 cases at 529/0/24.
Callable object members
Method signatures, function-valued properties and bounded interface inheritance share canonical callable and structural object types. The corpus is 559 cases at 535/0/24.
Nested expression ownership
Parentheses, object-property values and array elements build recursive expression subtrees; contextual callbacks now flow through the first two positions. The corpus is 563 cases at 539/0/24.
Index and callable object signatures
Bounded string/number index signatures and one callable object signature live on canonical structural types and reuse callable checking. The corpus is 569 cases at 545/0/24.
Compiler preview contract · qualified
The bounded CLI, project, semantic, diagnostic and output contract is frozen and qualified. The candidate builds reproducibly and its supported JavaScript intersection runs in both Node and JS++.
Contract inventory · complete
A machine-readable manifest now separates checked semantics from emitted-only syntax, freezes CLI/module/project exclusions and names the positive and negative multi-file preview projects.
Diagnostic contract · complete
Diagnostics now carry stable TSCC codes, deterministic ordering and pinned non-pretty formatting; unknown options, missing values and mixed project/source invocation have explicit CLI codes and exit behavior.
Project and output contract · complete
ES2022 and the supported module/JSX modes are enforced; project roots and output are deterministic; unknown configuration fails visibly; and default partial emission versus noEmitOnError all-or-none behavior is executable evidence.
Cross-module semantic closure · complete
Relative named imports now receive cloned exported callable and structural types. Unit-local type IDs never cross the graph boundary, and the frozen negative project proves imported argument mismatches are rejected.
Module-free JS++ intersection · complete
A frozen typed object, tuple and function program compiles through production TSCC and returns 42 under both Node and JS++. The seven-case boundary does not imply module loading or general JavaScript compatibility.
Compiler preview candidate · qualified
The bounded Linux candidate passes 555/0/24, the 7/7 Node/JS++ intersection, frozen and representative projects, ASan/UBSan, 400 deterministic mutations, a loose startup guardrail and byte-identical archives. Leak checking remains external under the managed ptrace runner.
Clean pause baseline
CP43-75 have added declaration/export facts, practical resolution/configuration, hermetic libraries, generics/inference, overloads, classes, CFG narrowing, richer collections, advanced types, bounded JSX semantics, source/declaration maps and incremental output. CP71-73 hardened the expanded compiler; CP74-75 closed the JSX correctness defects exposed during validation.
Compatibility matrix + real-project decision · complete
The suite now records 33 capability areas, 12/12 multi-file/project checks and nine real-package probes across three installed source distributions. Those failures selected the next implementation order.
High-frequency standard-library member semantics · next
Prioritize Array/tuple methods, String members and selected Object/Symbol members that block current real-project probes.
Flow and definite-assignment parity
Reduce practical control-flow false positives and strictness mismatches exposed by external projects without weakening supported diagnostics.
Practical tsconfig breadth
Implement the configuration options most frequently blocking project adoption before broadening exotic language semantics.
Parser/type-grammar reductions
Minimize and close the remaining parser/type grammar families exposed by the real-project corpus.
Real-project rerun and next decision
Rerun the same projects, measure which blockers moved, and select the next slices from retained evidence.
Steps 02–05 are now concrete: tscc has durable syntax and statement-expression ownership, one program graph, bounded lexical and cross-module symbols, canonical primitive/union/callable/object/array/tuple facts, contextual checking and explicit output policy. The frozen preview baseline remains 555/0/24 across 579 cases, while the current external suite is 600/0/18 across 618 cases plus 12/12 multi-file/project evidence and the retained 7/7 Node/JS++ runtime intersection.
The external memory campaign is complete for the CP75 baseline. That decision gate has now run. CP81-85 prioritize standard-library members, flow/definite-assignment parity, practical tsconfig breadth, reduced parser/type grammar blockers and a controlled real-project rerun before any broader compatibility campaign.
The hybrid architecture hypothesis
source + durable structural syntax
├── binder → symbols → types → diagnostics
└── validated source edits → JavaScript emission tscc does not need to throw away its fast source-preserving emitter to learn program meaning. Semantic nodes can retain original spans, while validated edits continue to own changed bytes. That direction remains a hypothesis to measure rather than dogma.
How checkpoints earn their place
Each slice should begin with the exact contract, ask TypeScript for reference behavior where relevant, add independent and focused tests, implement every required layer, inspect and run emitted JavaScript, stress scope and malformed neighbors, then rerun the full evidence wall. Semantic progress that silently damages transpilation is not progress.