ReviewOS

home-lang/home

fix(ts): transfer Extract through imported conditional handlers

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

Parent: #548

Problem

Program declaration schemas already preserve conditional types, mapped key identity, and imported overload order, but standard Extract<T, U> is not a transferable utility expression. A source-owned alias that uses Extract therefore makes its imported callable graph unsupported and collapses contextual callback parameters to any.

This is the remaining structural delta behind Zod 4.5.2's VisitHandlers template after #666 and #667.

Fair strict reduction

owner.ts defines a discriminated A | B union and:

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

The consumer imports visit, passes property a, proves the callback item is A, and keeps independent invalid controls: assignment of A to number, access to A.b, and a missing member on boolean.

TypeScript 6.0.3 and the native TypeScript preview report exactly TS2322 + TS2339 + TS2339. ReleaseFast Home reports two false TS7006 diagnostics and misses all three controls.

Acceptance

  • Represent and lower standard Extract<T, U> through the general Program schema/type machinery with TypeScript's distributive union semantics.
  • Preserve type-parameter identity through mapped-property specialization and conditional evaluation.
  • Keep imported overload ordering and unique object-property selection from #667.
  • Add negative controls for nonmatching union members, a never extraction/fallback, ambiguity, generics, and optional mapped members.
  • Add permanent schema and imported Program regressions.
  • Match the exact TypeScript 6.0.3/native reduction without weakening diagnostics.
  • Run complete Program/checker suites, ReleaseFast, formatting, whitespace, and required Pickier.
  • Run the unchanged Zod 4.5.2 identity admission guard twice; require zero additions and document exact removals or an unchanged result.
  • Publish detailed evidence and a brief linked README table update.

No Zod path/name/property/line special cases, shallow source-text recognizers, fabricated object shapes, or callback-value-driven overload selection.

8 days ago

Implementation landed directly on main in 40160d029 (fix(ts): transfer Extract through imported handlers (#668)).

What changed:

  • Program schemas represent exact standard Extract<T, U> as a lossless utility expression instead of rejecting the containing declaration.
  • Consumer lowering resolves the source and evaluates the canonical distributive conditional T extends U ? T : never through the existing conditional engine.
  • Mapped-key substitution, conditional distribution, overload ordering, and #667's unique property-shape selection remain independent mechanisms.
  • Other utility kinds retain their prior contextual-only/unsupported admission rules; no corpus/path/name/property/line special case was added beyond recognizing the standard Extract utility.

Permanent coverage:

  • Schema regression proves Extract survives both branches of a conditional alias nested under an optional mapped handler and an imported overload set.
  • Program regression proves property a specializes A | B to A, excludes B, preserves boolean, and reports no false TS7006/TS2345.
  • ItemOfKind<never> proves the outer [Extract<...>] extends [never] fallback resolves to the complete A | B union.
  • Existing #667 ambiguity, generic-overload, mismatch, and optional-mapped controls remain green.

Exact ReleaseFast oracle:

  • TypeScript 6.0.3, native TypeScript preview, and Home report the same four deliberate codes: TS2322 x2 and TS2339 x2.
  • The selected callback item is A; Home's fallback value is A | B (TypeScript displays its Item alias).
  • No TS7006 or TS2345.

Validation:

  • Program suite: 194/194 passed.
  • Full checker suite: passed.
  • ReleaseFast: passed.
  • zig fmt --check and git diff --check: passed.
  • Required full Pickier run: unchanged repository baseline of 22,427 existing findings (11,834 errors, 10,593 warnings).

Unchanged pinned Zod 4.5.2 graph, two independent candidate runs:

  • Candidate runs and the #667 baseline are byte-identical, stderr SHA-256 0590e3b2b593d2e2c0abb32f9f732d45f6d1701f3c2f906d07975ddf39c0bbc9.
  • 400 diagnostics and 395 unique path/line/column/code identities on both sides.
  • Normalized identity SHA-256 86df9bf4b128d164b88a96d4dfa2441094dbeeaa514b2587fa73c5ac0f3cdab5.
  • Exact delta: 0 removals, 0 additions.
  • The unchanged result proves another source-schema edge in Zod's much larger VisitHandlers graph remains unsupported; #668 does not approximate that graph.
  • Timings excluded on the contended shared host.

README and detailed docs remain and will land separately.

8 days ago

Documentation is complete on main in 13d74ca52 (docs(ts): publish imported Extract audit (#668)). The README links the detailed exact oracle and unchanged Zod admission table.

All acceptance gates are complete. The standard Extract reduction is fixed without weakening diagnostics; the full production graph remains byte-identical with zero identity additions. Closing #668 while the next issue isolates the additional unsupported edge in Zod's larger handler declaration graph.

Sign in to comment on this issue.