ReviewOS

home-lang/home

fix(ts): specialize mapped contextual members by property key

#666
Closed chris opened this 8 days ago ·
8 days ago

Parent: #548

A strict two-file reduction isolates mapped object-literal contextual typing across an import. For type Handlers = { [K in Kind]?: (item: Item<K>, rewritten: boolean) => Item }, the property a: (item, rewritten) => ... must specialize K to "a".

TypeScript 6.0.3 and the native TypeScript preview infer Item<"a"> and report only the deliberate TS2322 and TS2339 controls. Home leaves the callback parameter as Item<K>, adds a false TS2322 for K to "a", and adds a false whole-argument TS2345.

The checker currently substitutes a mapped property key only when the template contains a directly recognized indexed-access shape. A general callable template can carry the mapped key through nested generic arguments instead.

Acceptance criteria:

  • specialize mapped member templates with the concrete object-literal property key
  • preserve unrelated outer generic parameters and optional mapped members
  • remove the false whole-object TS2345 without weakening negative property checks
  • add a permanent imported positive/negative regression
  • match TypeScript 6.0.3 and the native preview exactly on the standalone oracle
  • run full checker and Program suites, ReleaseFast, and the unchanged Zod diagnostic audit with zero additions
  • document any admitted corpus change in the performance record and README
8 days ago

Implementation is on main in d529265.

The mapped payload now retains its key-parameter declaration identity through interning, substitution, Program lowering, and cross-pool transfer. Concrete object-literal property projection substitutes that identity with the property string literal, so nested callable templates such as Item<K> specialize without any alias, member-name, path, or corpus special case.

Validation:

  • exact two-file oracle: TypeScript 6.0.3, native TypeScript preview, and ReleaseFast Home all report only TS2322 (Item<"a"> to number) and TS2339 (missing on boolean)
  • no TS7006, false key-assignment TS2322, or false whole-argument TS2345
  • permanent imported positive/negative Program regression
  • complete Program suite passes
  • complete checker suite passes; focused type-transfer regression confirms the mapped key identity relocates
  • ReleaseFast passes
  • exact parent bb52bd4ab versus candidate d5292655c Zod 4.5.2 A/B: 400 diagnostics / 395 unique identities in both arms, identical normalized identity sets, and byte-identical stderr SHA-256 0590e3b2b593d2e2c0abb32f9f732d45f6d1701f3c2f906d07975ddf39c0bbc9; zero additions and zero removals
  • two candidate Zod runs are byte-identical
  • zig fmt --check and git diff --check pass
  • required repository-wide Pickier run remains red on existing debt: 22,427 findings (11,834 errors, 10,593 warnings)

Timing remains excluded because the shared host was contended and Zod still has diagnostics. I am publishing the detailed record and README summary next.

8 days ago

Completed on main in d529265 and documented in d748112: https://github.com/home-lang/home/blob/main/docs/docs/TS_PERFORMANCE.md#imported-mapped-contextual-members

The exact strict two-file oracle now matches TypeScript 6.0.3 and the native preview with only the deliberate TS2322 and TS2339 controls. The exact parent/candidate Zod A/B is byte-identical at 400 diagnostics / 395 unique identities, with zero additions and zero removals. Full checker and Program suites, focused cross-pool transfer coverage, ReleaseFast, formatting, and diff gates pass. Closing as completed.

Sign in to comment on this issue.