ReviewOS

home-lang/home

fix(ts): contextually type imported overloaded object-literal calls

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

Parent: #548

A strict two-file reduction adds an ordinary callable overload before the mapped-handler overload fixed by #666:

export type Handler = (item: Item, rewritten: boolean) => Item;
export type Handlers = { [K in Kind]?: (item: Item<K>, rewritten: boolean) => Item };
export declare function visit(handler: Handler): Item;
export declare function visit(handlers: Handlers): Item;

For visit({ a: (item, rewritten) => ... }), TypeScript 6.0.3 and the native TypeScript preview select the object-handler candidate for contextual typing, infer Item<"a"> and boolean, and report only deliberate TS2322/TS2339 controls. ReleaseFast Home emits TS7006 for both callback parameters and misses both controls. Removing the first overload makes the same program pass under #666, isolating overload-candidate contextual typing rather than mapped-key substitution itself.

The same pattern appears in the pinned Zod 4.5.2 graph: visit has callable and mapped-handler overloads, while classic and mini in-out.ts retain 16 TS7006 diagnostics across mapped visitor callbacks.

Acceptance criteria:

  • contextually type object-literal arguments against applicable imported overload candidates
  • retain #666 concrete mapped-key specialization inside the chosen contextual candidate
  • preserve overload order, ambiguity behavior, unrelated generic parameters, and optional mapped members
  • retain negative TS2322 and TS2339 controls; do not suppress errors or widen callbacks to any
  • add a permanent imported overload 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 an exact unchanged Zod parent/candidate identity audit with zero additions
  • document any admitted corpus change in the performance record and README
8 days ago

Implementation landed on main in b6f5eef4a (fix(ts): contextually type imported overload objects (#667)).

What changed:

  • Program schemas now transfer multiply declared functions as an ordered intersection of their bodyless overload signatures. A concrete implementation body is deliberately excluded from the public call surface.
  • Contextual object-literal checking filters arity-compatible overloads by declared property ownership only. It selects a signature only when exactly one candidate remains; callback values are not checked during selection, so ordinary overload resolution remains authoritative.
  • Mapped property domains use the existing constraint relation and preserve the concrete mapped-key specialization added by #666.
  • No package, symbol, property, or benchmark-specific special case was added.

Permanent regressions:

  • Imported generic/optional first overload plus imported mapped-handler second overload: no TS7006/TS2345; exact deliberate TS2322 + TS2339 controls.
  • Ambiguous same-property overloads retain first-declaration contextual order, matching TypeScript.
  • A property owned by no overload remains uncontextualized (TS7006), rather than selecting an inapplicable signature.

Validation:

  • Program suite: 193/193 passed.
  • Full checker suite: passed.
  • zig build -Doptimize=ReleaseFast: passed.
  • zig fmt --check and git diff --check: passed.
  • Full required Pickier run completed at the unchanged repository baseline: 22,427 existing problems (11,834 errors, 10,593 warnings); changed files are Zig-only.

Exact two-file oracle:

  • TypeScript 6.0.3, native TypeScript preview, and ReleaseFast Home all report exactly the deliberate TS2322 (Item<"a"> to number) and TS2339 (missing property on boolean).
  • Home reports no false TS7006 and no false TS2345.

Unchanged Zod 4.5.2 benchmark (tsconfig.benchmark.json), two candidate runs:

  • Deterministic byte-for-byte candidate output: SHA-256 3212f2598cc37ba0eb8a98a14c0ddfe82158ee4797ee75ec8f5d8565d5414774.
  • Baseline and candidate: 400 diagnostics, 395 unique path/line/column/code identities.
  • Identity SHA-256 is unchanged: 86df9bf4b128d164b88a96d4dfa2441094dbeeaa514b2587fa73c5ac0f3cdab5.
  • Exact identity delta: 0 removals, 0 additions.
  • The 16 in-out.ts TS7006 diagnostics remain because Zod's real handler template includes a deeper conditional/Extract schema outside this overload-transfer slice; timings were excluded because the shared host was contended.

README and detailed benchmark documentation are the remaining acceptance item and will land separately.

8 days ago

Documentation is now on main in 9c13f230f (docs(ts): publish imported overload object audit (#667)). The README links the detailed audit and carries the Zod summary table.

The final same-working-directory production rerun strengthens the earlier evidence: the #666 baseline and both independent #667 candidate stderr files are byte-identical, SHA-256 0590e3b2b593d2e2c0abb32f9f732d45f6d1701f3c2f906d07975ddf39c0bbc9. The normalized identity delta remains 0 removals / 0 additions.

All #667 acceptance items are complete. The deeper conditional/Extract owner-schema gap that keeps Zod's 16 target TS7006 diagnostics is separate follow-up work; #667 did not approximate or special-case it.

Sign in to comment on this issue.