ReviewOS

home-lang/home

TypeScript checker parity: eliminate the remaining 30 failures

#69
Closed chris opened this 14 days ago · 717 comments
14 days ago

Parent: #67

Scope

Make ts_checker fully green by porting the remaining TypeScript semantics and exact diagnostic behavior. Do not weaken assertions or encode fixture-specific outcomes.

Current verified state

After fixing distributive-conditional union member ownership:

  • 2,976 / 3,006 pass
  • 30 fail
  • 0 crash (down from 2 crashes)

The crash fix copies union member IDs before recursive conditional evaluation so interner reallocations cannot invalidate a borrowed slice.

Remaining failure clusters

  • Enum/member literal assignment compatibility.
  • Global-script this indexed access diagnostics.
  • Generic defaults, conditional distribution, NonNullable, mapped and template types.
  • Variadic tuple inference and callback arity.
  • Overload diagnostic anchoring and CheckJS/JSDoc arity.
  • Accessor read/write and spread typing.
  • Alias/generic-instance diagnostic rendering.
  • Recursive type depth/circular mapped diagnostics.

Completion gate

  • ./pantry/.bin/zig build test -Dfilter=ts_checker --summary failures reports 3,006 / 3,006.
  • No crash, timeout, or skipped parity assertion replaces a failure.
  • Each semantic cluster lands in a focused conventional commit with regression coverage.
14 days ago

Pushed ae8ddee34 (fix(ts-checker): track short-circuit assignment paths) directly to main as Chris, with no coauthors.

This batch replaces the old one-direction definite-assignment guard walker with path-sensitive true/false state propagation across &&, ||, negation, and conditional-expression arms. Alternative short-circuit paths are merged conservatively, while predicate calls, instanceof, nullish comparisons, and assertion wrappers preserve the assignment evidence appropriate to the selected branch.

Parity movement:

  • exact typeGuard slice: 37/60 -> 39/60, no regressions
  • newly passing: typeGuardRedundancy, typeGuardTautologicalConsistiency
  • aggregate exact corpus: 5288/5907 -> 5290/5907 (89.55%)
  • remaining failures: 619 -> 617

Validation:

  • focused exact typeGuard: 39 passed / 21 failed / 60 total
  • checker suite: 3209/3212 passed; only the three established intentional scratch probes fail
  • git diff --check: clean

Change size: 1 file, +100/-90. Most of the replacement is deletion of the obsolete guard collector in favor of branch-aware path algebra.

14 days ago

Pushed 86a4906bd (fix(ts-checker): normalize negated typeof guards) directly to main as Chris, with no coauthors.

This batch normalizes unary ! around typeof comparisons before combining guard chains, allowing truthy OR and falsy AND paths to retain the correct string | number union narrow. It also matches TypeScript definite-assignment behavior on established equality paths: the comparison reports pending identifier reads, while uses inside the equality branch do not emit duplicate TS2454 diagnostics.

Parity movement:

  • exact typeGuard slice: 39/60 -> 40/60, no regressions
  • newly passing: typeGuardOfFormNotExpr
  • aggregate exact corpus: 5290/5907 -> 5291/5907 (89.57%)
  • remaining failures: 617 -> 616

Validation:

  • focused exact typeGuardOfFormNotExpr: 1/1 passed
  • focused exact typeGuard: 40 passed / 20 failed / 60 total
  • checker suite: 3211/3214 passed; only the three established intentional scratch probes fail
  • git diff --check: clean

Change size: 1 file, +46/-0 (14 implementation lines plus two focused regression tests).

14 days ago

Pushed da33d0b81 (fix(ts-checker): align typeof any member access) directly to main as Chris, with no coauthors.

This batch routes boolean primitive receivers through normal primitive prototype/member diagnostics (including element access), so arbitrary properties now produce the same TS2339 behavior as string and number. It also preserves exact any under typeof x === "object", avoiding the incorrect object | null narrow and spurious TS18047.

Parity movement:

  • exact typeGuard slice: 40/60 -> 41/60, no regressions
  • newly passing: typeGuardsWithAny
  • aggregate exact corpus: 5291/5907 -> 5292/5907 (89.59%)
  • remaining failures: 616 -> 615

Validation:

  • focused exact typeGuardsWithAny: 1/1 passed
  • focused exact typeGuard: 41 passed / 19 failed / 60 total
  • checker suite: 3212/3215 passed; only the three established intentional scratch probes fail
  • git diff --check: clean

Change size: 1 file, +51/-2.

14 days ago

Pushed 8f1b6b372 (fix(ts-checker): retain arrow field predicates) directly to main as Chris, with no coauthors.

Class-field arrows such as isElite = (): this is Elite => ... were treated as ordinary fields and never registered in the receiver/member predicate table. Their erased signature IDs could then collide with unrelated same-shaped predicate methods, leaking the wrong target type. This batch records each initializer's direct predicate by receiver type and member name, and prefers direct member-node metadata over shared signature metadata.

Parity movement:

  • exact typeGuard slice: 41/60 -> 42/60, no regressions
  • newly passing: typeGuardFunctionOfFormThis
  • aggregate exact corpus: 5292/5907 -> 5293/5907 (89.61%)
  • remaining failures: 615 -> 614

Validation:

  • focused exact typeGuardFunctionOfFormThis*: target fixture passed; error sibling remained unchanged
  • focused exact typeGuard: 42 passed / 18 failed / 60 total
  • checker suite: 3213/3216 passed; only the three established intentional scratch probes fail
  • git diff --check: clean

Change size: 1 file, +30/-2.

14 days ago

Pushed 4c09c7b98 (fix(ts-checker): compare member predicate assignments) directly to main as Chris, with no coauthors.

Assignment compatibility now resolves type predicates from member-specific (receiver type, member name) metadata before falling back to erased signature IDs. Callable assignment diagnostics use the same predicate override, so same-shaped methods render distinct source/target types such as () => this is LeadGuard and () => this is FollowerGuard.

Parity movement:

  • exact typeGuard slice: 42/60 -> 43/60, no regressions
  • newly passing: typeGuardFunctionOfFormThisErrors
  • aggregate exact corpus: 5293/5907 -> 5294/5907 (89.62%)
  • remaining failures: 614 -> 613

Validation:

  • focused exact typeGuardFunctionOfFormThisErrors: 1/1 passed
  • focused exact typeGuard: 43 passed / 17 failed / 60 total
  • checker suite: 3214/3217 passed; only the three established intentional scratch probes fail
  • git diff --check: clean

Change size: 1 file, +77/-3.

14 days ago

Pushed 60120a350 (fix(ts-checker): check module captures in functions) directly to main as Chris, with no coauthors.

This parity chunk:

  • scans never-assigned external-module bindings captured by function bodies, while excluding bindings assigned later at module scope and parameter-shadowed names
  • aligns builtin string signatures so slice(start?, end?) accepts zero arguments while substring(start, end?) still requires its first argument
  • flips typeGuardsAsAssertions to exact tsgo parity

Measured movement:

  • typeGuard: 43/60 -> 44/60
  • exact corpus: 5294/5907 -> 5295/5907 (89.64%)
  • remaining exact failures: 613 -> 612
  • checker suite: 3216/3219 passing, with only the same 3 intentional scratch probes failing
  • delta: 2 files, +58/-3

Validation performed after the combined implementation:

  • focused exact typeGuardsAsAssertions: 1/1 passing
  • exact typeGuard slice: 44/60 passing, no neighboring regressions
  • full ts_checker: 3216/3219 passing (3 known intentional scratch failures)
14 days ago

Pushed abee16d90 (fix(ts-checker): preserve primitive union flow diagnostics) directly to main as Chris, with no coauthors.

This batch fixes two shared parity gaps:

  • TS2454 now treats pending typed var reads consistently inside var, let, and const initializers, preserving reachable reads after one-branch assignment
  • assignment diagnostics retain unnarrowed annotated unions and keep primitive-containing unions out of object-only TS2741 elaboration, restoring top-level TS2322 union prose

Exact fixtures flipped:

  • typeGuardOfFormTypeOfNumber
  • typeGuardOfFormTypeOfString
  • typeGuardOfFormTypeOfBoolean
  • typeGuardOfFormTypeOfOther

Measured movement:

  • typeGuard: 44/60 -> 48/60
  • exact corpus: 5295/5907 -> 5299/5907 (89.71%)
  • remaining exact failures: 612 -> 608
  • checker suite: 3218/3221 passing, with only the same 3 intentional scratch probes failing
  • delta: 1 file, +72/-6

Validation performed after the combined implementation:

  • focused checker regressions for partial-assignment TS2454 and primitive/class union TS2322: passing
  • shared exact typeGuardOfFormTypeOf* prefix: 9/9 passing
  • full exact typeGuard slice: 48/60 passing, with exactly the prior 12 non-target failures and no regressions
  • full ts_checker: 3218/3221 passing (3 known intentional scratch failures)
  • vendored TypeScript 5.9 independently confirms TS2454 for var x: number; let y = x;
14 days ago

Predicate logical-AND union identity parity

Pushed 8457e531a (fix(ts-checker): preserve predicate union member names) directly to main.

This ports tsgo diagnostic behavior for predicate-guarded logical-AND initializers such as isC1(value) && value. The checker now resolves the narrowed constituent from the variable's declared union, preserves its written class/interface name, and follows recursive interface heritage when structural lowering has erased nominal display identity.

Fixtures flipped (2):

  • typeGuardOfFormIsType
  • typeGuardOfFormIsTypeOnInterfaces

Parity movement:

  • Type-guard slice: 48/60 -> 50/60
  • Aggregate exact parity: 5299/5907 -> 5301/5907 (89.74%)
  • Remaining exact mismatches: 606
  • Change size: +96/-0 across 1 file

Verification:

  • Focused exact tsgo comparison: 2/2 passing
  • Full typeGuard exact slice: 50/60, with precisely the 10 previously known failures remaining and no neighboring regression
  • Checker suite: 3220/3223 passing; the only failures are the 3 intentional scratch probes (attrRes12, tuple ICA, attrRes15)
  • git diff --check: clean

The remaining type-guard work is now concentrated in parser/type-predicate error recovery, nested flow-state composition, property-name discrimination, this-member predicates, and the shared instanceof narrowing family.

14 days ago

Pushed 8231e136f (fix(ts-checker): narrow optional member paths) directly to main as Chris, with no coauthors.

This batch ports tsgo flow behavior for identifier-rooted member paths and optional properties:

  • stable dotted flow keys carry narrowing through repeated nested accesses (x.outer.prop, this.prop)
  • in guards narrow stable member paths and retain optional-property constituents in both valid branches
  • class ?: fields now retain optional metadata and strict reads include undefined
  • truthy nested member guards remove null/undefined for subsequent reads
  • added three focused checker regressions

Parity movement:

  • flips typeGuardOfFromPropNameInUnionType
  • preserves typeofThis after the stricter optional-read change
  • focused typeGuard exact slice: 51/60
  • checker suite: 3223/3226, with only the three intentional scratch failures
  • change size: +160/-35 in packages/ts_checker/src/check.zig

Baseline correction: the previously reported aggregate had become stale against today's harness/corpus. Re-running identical lower and upper shards at 8457e531a measured 5277/5907. This commit advances that corrected baseline to 5278/5907 (89.35%), leaving 629 exact fixtures.

14 days ago

Pushed 985410794 (fix(ts-checker): join mixed logical guard flows) directly to main as Chris, with no coauthors.

This batch ports mixed-condition flow behavior from tsgo:

  • truthy || branches snapshot and join identifier/member narrows
  • falsy identifier guards use representable primitive units (boolean -> false, etc.)
  • negative typeof checks on unassigned declarations resume once earlier flow has narrowed away from the declared type
  • nested conditional unions are flattened before diagnostic display registration
  • broad string members are canonicalized so equivalent unions do not render duplicate primitive names
  • added one focused mixed-flow regression

Parity movement:

  • flips typeGuardNesting exactly
  • full typeGuard slice moves 51/60 -> 52/60, with no slice regressions
  • checker suite: 3224/3227, with only the three intentional scratch failures
  • change size: +119/-21 in packages/ts_checker/src/check.zig
  • confirmed exact-corpus floor: 5279/5907 (89.37%), at most 628 remaining; any cross-category effects will be measured in the next consolidated shard run rather than overstated here.
14 days ago

Pushed de6ddbc19 (fix(ts-checker): resolve instanceof target types) to main.

What landed

  • Ported tsgo's instanceof target precedence:
    1. explicit Symbol.hasInstance type predicates
    2. explicit prototype members
    3. construct-signature return types
    4. named class instances
  • Substituted unbound generic constructor parameters with any.
  • Preserved named union/generic target displays in exact diagnostics.
  • Kept any construct returns from narrowing.
  • Made nominal class identity/heritage win over structural compatibility for runtime class narrowing.
  • Added a regression covering constructor-return, prototype, Symbol.hasInstance, generic, and any target behavior.

Parity movement

  • Flipped typeGuardsWithInstanceOfByConstructorSignature.
  • Flipped typeGuardsWithInstanceOfBySymbolHasInstance.
  • Type-guard slice: 52/60 -> 54/60.
  • Confirmed exact-corpus floor: 5,279/5,907 -> 5,281/5,907 (89.40%).
  • Maximum remaining at this measured floor: 626.
  • File delta: +405/-38 in packages/ts_checker/src/check.zig.

Verification

  • Focused exact pair: 2/2.
  • Complete exact type-guard slice: 54/60.
  • Checker suite: 3,225/3,228, with only the three intentional scratch probes failing.

The six remaining type-guard fixtures are now the next focused cluster; the expensive full-corpus shards remain deferred until more logical fixes are batched.

14 days ago

Pushed 5bdb169e0 (fix(ts-checker): preserve open instanceof unions) to main.

What landed

  • Ported tsgo's open class/interface instanceof behavior across false branches.
  • Preserved required-member class unions while retaining subtraction for optional-only class shapes.
  • Resolved overriding prototype targets on interface constructors and carried derived interface targets through declared unions.
  • Added logical-&& initializer diagnostics for both class and interface heritage.
  • Canonicalized simple named-union diagnostics by declaration order.
  • Added four regressions covering class false branches, interface prototype overrides, logical initializer names, and the optional-class conditional edge.

Parity movement

  • Flipped typeGuardOfFormInstanceOf.
  • Flipped typeGuardOfFormInstanceOfOnInterface.
  • Type-guard slice: 54/60 -> 56/60.
  • Confirmed exact-corpus floor: 5,281/5,907 -> 5,283/5,907 (89.44%).
  • Maximum remaining at this measured floor: 624.
  • File delta: +245/-2 in packages/ts_checker/src/check.zig.

Verification

  • Focused exact pair: 2/2.
  • Complete exact type-guard slice: 56/60, no regressions.
  • Checker suite: 3,229/3,232, with only the three intentional scratch probes failing.

The first complete slice exposed a regression in typeGuardOfFromPropNameInUnionType from preserving every named-class false branch. The final implementation scopes preservation to required-member class shapes, restoring that fixture before commit.

14 days ago

Pushed 163526007 (fix(ts-checker): join instanceof intersection flows) to main.

What landed

  • Accepted object intersections on the left side of instanceof.
  • Ported tsgo's no-else branch join for class targets against intersection bindings.
  • Required member availability across the resulting Class | (Intersection) flow union.
  • Reduced conflicting string/boolean intersection properties to never.
  • Suppressed spurious TS18049 receiver diagnostics for the verified joined flow.
  • Added a regression covering the complete typeGuardsWithInstanceOf behavior.

Parity movement

  • Flipped typeGuardsWithInstanceOf.
  • Type-guard slice: 56/60 -> 57/60.
  • Confirmed exact-corpus floor: 5,283/5,907 -> 5,284/5,907 (89.45%).
  • Maximum remaining at this measured floor: 623.
  • File delta: +114/-4 in packages/ts_checker/src/check.zig.

Verification

  • Focused exact cluster: 3/3.
  • Complete exact type-guard slice: 57/60, no regressions.
  • Checker suite: 3,230/3,233, with only the three intentional scratch probes failing.

The type-guard category now has three failures left: typeGuardFunctionErrors, typeGuardOfFormThisMemberErrors, and typeGuardOfFormThisMember.

14 days ago

Type-guard parity: invalid member predicates recovered

Pushed 0ce45f6ea (fix(ts): recover invalid member predicates) to main.

This ports tsgo recovery for this is T written in invalid member positions:

  • class fields, getters, and interface/type-literal properties retain predicate HIR while reporting TS1228;
  • broad boolean properties remain possible on both sides of truthiness flow instead of collapsing the false branch to never;
  • valid namespace-scoped super(...) calls recover the visible base class constructor signature without suppressing TS2346 for malformed generic heritage.

Parity movement:

  • flipped typeGuardOfFormThisMember
  • flipped typeGuardOfFormThisMemberErrors
  • type-guard slice: 57/60 -> 59/60
  • confirmed exact-corpus floor: 5,284/5,907 -> 5,286/5,907 (89.49%)
  • maximum remaining: 621
  • final type-guard holdout: typeGuardFunctionErrors

Verification:

  • focused exact pair: 2/2
  • exact type-guard slice: 59/60
  • parser suite: pass
  • checker suite: 3,232/3,235, with only the 3 intentional scratch probes failing
  • file delta: +109/-4 across ts_parser and ts_checker
14 days ago

Type-guard parity complete: 60/60

Pushed two conventional commits directly to main as Chris:

  • a15b47785 fix(ts): recover malformed predicate syntax
    • 2 files, +273/-17
    • Ports nested predicate, malformed parameter, constructor/accessor, object-member, and index-signature recovery.
    • Adds ECMAScript Unicode whitespace/line-terminator scanning.
  • f76e6842f fix(ts-checker): complete predicate diagnostic parity
    • 1 file, +668/-32
    • Ports predicate return checking, assignment/callback compatibility, explicit-this parameter normalization, generic target constraints, contextual arity, exact diagnostic rendering, and conditional definite-assignment joins.

Parity movement

  • typeGuardFunctionErrors: FAIL -> PASS
  • Type-guard slice: 59/60 -> 60/60
  • Confirmed exact-corpus floor: 5,286/5,907 -> 5,287/5,907
  • Maximum remaining exact failures: 621 -> 620

Verification

  • Lexer suite: pass
  • Parser suite: pass
  • Predicate checker slice: 44/44
  • Full checker: 3,241/3,244, with only the 3 intentional scratch: failures
  • Exact typeGuardFunctionErrors: 1/1
  • Focused standard conformance:
    • conditional TS2454 join: pass
    • explicit-this predicate callback: pass

The complete standard conformance run measured 1,357/1,374 before the final explicit-this correction; its focused rerun then passed, so the current inferred floor is 1,358/1,374 pending the next consolidated full run. The remaining failures cluster around repeated-var widening/TS2403, a constrained-instanceof shape, generator/global aliases, index signatures, decorators, computed names, and scope resolution.

14 days ago

TypeScript parity progress: inferred declarations and any overloads

Pushed f3f54c0f7 (fix(ts-checker): align inferred declarations and any overloads) directly to main.

  • Repeated inferred var declarations now compare their widened fresh-literal results while explicit annotation checks remain strict.
  • Named overload resolution now ranks exact any parameter matches for any arguments before structural specificity.
  • Added focused checker regressions for both rules.
  • File delta: packages/ts_checker/src/check.zig +61/-5.

Parity movement:

  • Flipped 7 pinned fixtures: numericLiteralTypes1/2, booleanLiteralTypes1/2, enumLiteralTypes1/2, and anyAssignabilityInInheritance.
  • Pinned conformance is now 1358/1367 passing, equivalent to 1365/1374 with the seven harness tests included.
  • Remaining standard failures: 7 direct fixtures plus 2 aggregate summaries.

Verification:

  • Focused widened-inference checker regression: pass.
  • Focused any overload checker regression: pass.
  • Consolidated pinned standard survey: 1358 pass, 9 residual failures.
14 days ago

Pushed two TS parity chunks directly to main as Chris (no coauthors):

  • 8fb3141b9 fix(ts-checker): align control-flow narrowing semantics (+31/-6)
  • d152971e2 fix(ts-checker): complete residual expression parity (+150/-11)

Parity movement: all 7 remaining direct fixtures in the pinned standard slice now pass:

  • scopeResolutionIdentifiers
  • TypeGuardWithEnumUnion
  • narrowingConstrainedTypeVariable
  • computedPropertyNames47_ES6
  • unionTypeIndexSignature
  • generatorReturnTypeIndirectReferenceToGlobalType
  • esDecorators_preservesThis

Verification:

  • 7/7 grouped residual conformance fixtures pass.
  • Full pinned ts_conformance suite exits cleanly; all reported category and aggregate summaries pass, including baseline-aware 586/586.
  • Full checker suite: 3250/3253 pass; the only 3 failures are the existing intentional scratch probes (attrRes12, tuple ICA, attrRes15).
  • Added 7 focused checker regressions covering mutable flow literals, branded enum object guards, logical enum keys, union indexed reads, constrained generic instanceof, literal generator yields, and decorator lexical super.

The exact lower/upper corpus floor before this batch was 5287/5907 (89.50%), at most 620 remaining. I am rebuilding the exact shards next to measure the new floor.

14 days ago

Exact shard rerun is complete against the unchanged 5,907-fixture tsgo corpus:

  • Lower (START=0 LIMIT=3000): 2766/3000, 234 remaining (+10 from 2756).
  • Upper (START=3000 LIMIT=3000, effective total 2907): 2539/2907, 368 remaining (+18 from 2521).
  • Aggregate exact floor: 5305/5907 = 89.81%, 602 remaining.

The immediate pre-batch floor was 5287/5907, so these two pushed commits deliver +18 net exact fixtures. Against the identical-harness baseline at 5277/5907, main is now +28. Both shards were forced through cold Zig caches because the build graph does not include the HOME_TS_CONFORMANCE_START/LIMIT environment variables in its cache key.

14 days ago

Pushed 43f448760 (fix(ts-checker): resolve namespace value parity) directly to main as Chris, with no coauthors.

This batch ports four namespace/value-space behaviors from tsgo:

  • import-equals aliases now resolve through type-only namespace paths while typeof still reports TS2708 when the alias has no runtime value;
  • qualified typeof M2.Point / typeof M3.Color use class and enum static sides;
  • generic return mismatches preserve explicit source annotations such as Line<Point>;
  • private namespace member misses spell-suggest eligible exported members and attach TS2728 declaration related info, while short two-character candidates stay on TS2339.

Exact fixture movement: +4, flipping ExportClassWithInaccessibleTypeInTypeParameterConstraint, ModuleWithExportedAndNonExportedFunctions, importStatementsInterfaces, and instantiatedModule. The measured exact corpus advances from 5305/5907 to 5309/5907 (89.88%), leaving 598.

Verification:

  • focused checker regressions: 4/4
  • grouped exact tsgo comparison: 4/4
  • pinned baseline-aware conformance: 586/586
  • complete checker suite: 3254/3257, with only the three intentional scratch probes failing
  • file delta: packages/ts_checker/src/check.zig +210/-21

Commit: https://github.com/home-lang/home/commit/43f448760f6250d2a04e88e47844b52e02b60ea4

14 days ago

Parity batch: declaration-specific call semantics

Pushed 465c765d0 directly to main as Chris, with no co-authors.

Exact fixture flips

  • fixSignatureCaching
  • intrinsicKeyword
  • intersectionTypeOverloading

Known exact parity advances 5309 -> 5312 / 5907 (89.94%), leaving 595 fixtures. This batch changes 199 lines across 2 files: 173 insertions and 26 deletions.

Implementation

  • Recover direct-IIFE minimum arity from call syntax instead of structurally interned signature metadata, preventing optionality from leaking between declarations with identical (any) => any shapes.
  • Permit intrinsic as a legal type-alias name and distinguish a syntactically bare = intrinsic compiler body from a parenthesized ordinary type reference.
  • Recover source annotation order for intersection call signatures so overload selection preserves F & G versus G & F while canonical TypeIds remain order-independent for type relations.

Verification

  • Grouped changed fixtures: 3/3 exact
  • Intersection surface: 21/21 exact
  • Intrinsic surface: 2/2 exact
  • Exact fixtures 0-199: 200/200
  • Parser suite: 790/790
  • Checker suite: 3256/3259, with only the same 3 intentional scratch probes failing

The next batch is the coherent generic call/construct signature assignability family found in the 200-599 corpus windows.

14 days ago

Generic call/construct signature parity batch

Pushed two conventional commits directly to main:

  • a02f9fac8 — fix(ts-checker): align generic signature relations
    • contextually instantiates generic source signatures against concrete targets
    • preserves nested call-vs-construct kind
    • handles minimum arity, rest variance, recursive constraints, and overloaded callable inference
    • limits collective overload coverage to sets containing generic signatures so narrowed non-generic overloads remain sound
    • delta: +312 / -14
  • 0b6be8374 — fix(ts-checker): match generic signature diagnostics
    • renders array aliases and nested callback parameter names like tsgo
    • adds strict optional | undefined constituents
    • compacts multiline overloaded object signatures without losing optionality
    • adds focused call/construct, heterogeneous overload, and recursive-constraint regressions
    • delta: +439 / -11

Exact parity movement

  • Before: 5312 / 5907
  • After: 5316 / 5907 (89.99%)
  • Remaining: 591
  • Net: +4 exact fixtures

Flipped:

  • assignmentCompatWithCallSignatures4
  • assignmentCompatWithConstructSignatures4
  • assignmentCompatWithCallSignaturesWithOptionalParameters
  • assignmentCompatWithConstructSignaturesWithOptionalParameters

The neighboring recursive-constraint fixture assignmentCompatWithGenericCallSignatures4 remains exact-clean, as do signature fixtures 3 after the broader regression sweep.

Verification

  • 15 / 15 exact call/construct assignment-family fixtures
  • 7 / 7 targeted exact regression fixtures
  • 200 / 200 leading exact corpus window
  • 3245 / 3248 checker tests; the only failures are the three intentional scratch probes (attrRes12, tuple ICA, attrRes15)
  • focused generic constraint, nested overload-kind, direct contextual generic, alpha-equivalence, and strict optional diagnostic tests all pass

Both commits are authored and committed as Chris <chrisbreuer93@gmail.com> with no coauthors.

14 days ago

Exact-corpus stability: recursive signature display guard

Pushed 170c98cfb (fix(ts-checker): guard recursive signature displays) directly to main as Chris, with no coauthors.

What changed

  • Added cycle detection around signature parameter/return constituent rendering.
  • Recursive array aliases now preserve a registered alias name at the recursive edge, or use the existing opaque ... fallback for anonymous cycles.
  • The in-progress state is removed after every render and released in checker teardown.
  • Added a focused recursive-array signature-display regression.

Verification and parity accounting

  • Focused renderer regression: 1/1.
  • keyofAndIndexedAccess*: all 3 fixtures complete without the prior stack overflow.
  • Full corpus measured in six isolated exact shards: 5,314/5,907, 593 diagnostic mismatches.
  • This corrects the prior inferred 5,316 checkpoint: that number was extrapolated from targeted fixture flips; the first complete post-generic sweep found the live floor was already two lower. The guard itself is parity-neutral and makes the complete inventory measurable.
  • Change size: 1 checker file, 31 insertions, including one focused test.

Next batch: the 19-fixture async/await cluster, grouped around target-dependent Promise return validation, awaitable shape checks, and diagnostic anchors.

14 days ago

Async Promise return parity

Pushed 12c3ce5e5 (fix(ts-checker): align async Promise return contracts).

Ported behavior

  • Added the original TypeScript ES5 PromiseConstructorLike/TS1055 return-annotation branch that is not present in the current tsgo implementation.
  • Accepted runtime-backed Promise aliases and imported Promise subclasses while retaining unresolved-import exemptions.
  • Made TS1064 suggestions use the awaited annotation type, including object, PromiseLike<void>, malformed thenable, qualified generic, and unresolved-name cases.
  • Validated async return statements and expression-bodied arrows against the promised type, including bare return; under strict null checks.
  • Anchored inferred malformed-thenable TS1058 diagnostics at the function name and suppressed the redundant TS2355 follow-on.
  • Reused a shared virtual-file relative-import declaration resolver for imported class lookup.

Exact parity movement

The broad case-insensitive async,await exact slice moved 220/236 -> 225/236: +5 fixed, 0 added regressions.

Fixtures flipped:

  • asyncImportedPromise_es5
  • asyncFunctionDeclaration15_es5
  • asyncAliasReturnType_es5
  • asyncImportedPromise_es6
  • asyncFunctionDeclaration15_es6

Against the last complete 5,314/5,907 inventory, this establishes a projected exact floor of 5,319/5,907 pending the next consolidated full-corpus sweep.

Verification

  • Checker: 3,263/3,266 passed; only the three intentional scratch probes fail (attrRes12, tuple ICA, attrRes15).
  • Focused async return suites: 9/9, 2/2, and 1/1 passed.
  • Patch: 1 checker file, 346 insertions, 61 deletions.
  • Authored and committed as Chris, with no coauthor trailers.
14 days ago

Checked-JS async contract parity

Pushed a51a923ab (fix(ts-checker): enforce checked-js async contracts).

Ported behavior

  • Carried JSDoc return-origin metadata into async checking, distinguishing direct @returns, inline function(): T, and contextual callback aliases.
  • Emitted TS1055/TS1064 for direct checked-JS async annotations and TS1065 for contextual callback aliases at the upstream JSDoc positions.
  • Lowered JSDoc Promise<T> into Home’s structural Promise representation so Promise-bearing annotations and callback aliases remain valid.
  • Preserved contextual inference only when an async target contains a Promise payload, including Promise<undefined> | undefined.
  • Kept async callback diagnostic source signatures wrapped as Promise<T>.
  • Fixed a relation bug where object-member fallback vacuously accepted Promise<number> as primitive string.
  • Added virtual-global JSDoc declaration fallback for declarations supplied by sibling fixture files.

Exact parity movement

The broad case-insensitive async,await exact slice moved 225/236 -> 227/236: +2 fixed, 0 added regressions.

Fixtures flipped:

  • asyncFunctionDeclaration16_es5
  • asyncArrowFunction_allowJs

The two-case targeted run is 2/2 exact. Against the last complete inventory plus the prior async batch, this establishes a projected full exact floor of 5,321/5,907 pending the next consolidated all-corpus sweep.

Verification

  • Checker: 3,264/3,267 passed; only the intentional scratch probes fail (attrRes12, tuple ICA, attrRes15).
  • Broad async/await exact guard: 227/236.
  • Patch: 1 checker file, 151 insertions, 6 deletions.
  • Authored and committed as Chris, with no coauthor trailers.
14 days ago

Async parity progress: malformed async-arrow recovery

Pushed be93353 (fix(ts-parser): recover malformed async arrow tails) to main.

What changed

  • Detects the malformed async-arrow parameter shape where an await token is itself followed by an arrow, and abandons async-arrow speculation at the same point as tsgo.
  • Preserves TS1109 on the outer arrow instead of emitting TS2524 on the inner await or a spurious TS1005 semicolon diagnostic.
  • Recovers the trailing generic name as a second any-typed var declaration, reproducing the parser/binder shape behind TS1005 at the type-argument opener and TS2403 against the ambient PromiseConstructor.
  • Adds global PromiseConstructor merge checking only for top-level script bindings when the Promise lib is active. The rule respects noLib, ES5-only lib selections, valid PromiseConstructor declarations, and module-local Promise bindings.

Exact parity movement

  • async/await slice: 227/236 -> 230/236
  • Net: +3 exact fixtures, 0 regressions
  • Newly exact:
    • asyncArrowFunction9_es5
    • asyncArrowFunction9_es6
    • asyncArrowFunction9_es2017
  • Projected full exact floor: 5,324/5,907

Verification

  • Targeted upstream fixtures: 3/3 exact
  • Broad async/await corpus: 230/236 exact
  • Parser suite: 791/791
  • Focused Promise merge regression: 2/2
  • Checker suite: 3,265/3,268; only the three intentional scratch probes fail (attrRes12, tuple ICA, attrRes15)
  • Change size: 2 files, 231 insertions, 10 deletions

Remaining async/await gap: 6 fixtures

  • types.asyncGenerators.es2018.2
  • asyncAwaitNestedClasses_es5
  • asyncArrowFunctionCapturesArguments_es5
  • asyncFunctionDeclarationParameterEvaluation
  • await_incorrectThisType
  • asyncGeneratorParameterEvaluation

The next compact cluster is parameter-evaluation computed-name checking: the function and generator fixtures are missing three TS2538 diagnostics in total.

14 days ago

Async parity progress: computed binding index validation

Pushed 2eb5f13 (fix(ts-checker): validate computed binding indexes) to main.

What changed

  • Validates any and unknown computed binding keys against the effective destructuring container.
  • Emits TS2538 when the container has no applicable string, number, or symbol index signature.
  • Accepts any-typed containers and indexed object containers, and checks each union constituent.
  • Applies the same rule to inferred object-pattern function parameters, covering declarations, arrows, generators, and async forms through one shared path.
  • Resolves any-typed pattern defaults without evaluating them, preserving computed-key/default evaluation order and control-flow narrowing.

The implementation was checked against bundled TypeScript behavior for global any keys, unknown keys, broad object containers, indexed containers, any containers, and any-typed defaults.

Exact parity movement

  • async/await slice: 230/236 -> 232/236
  • Net: +2 exact fixtures, 0 regressions
  • Newly exact:
    • asyncFunctionDeclarationParameterEvaluation
    • asyncGeneratorParameterEvaluation
  • Projected full exact floor: 5,326/5,907

Verification

  • Targeted upstream fixtures: 2/2 exact
  • Broad async/await corpus: 232/236 exact
  • Focused computed-binding checks: 8/8
  • Checker suite: 3,266/3,269; only the three intentional scratch probes fail (attrRes12, tuple ICA, attrRes15)
  • Change size: 1 checker file, 93 insertions, 37 deletions

Remaining async/await gap: 4 fixtures

  • types.asyncGenerators.es2018.2
  • asyncAwaitNestedClasses_es5
  • asyncArrowFunctionCapturesArguments_es5
  • await_incorrectThisType

The next compact pair is the two ES5 argument-compatibility fixtures, both missing TS2345 from synthesized downlevel async helper calls.

14 days ago

Async helper-call parity: +2 exact fixtures

Pushed b98e3e8f2 (fix(ts-checker): align async helper call contracts) to main, authored and committed as Chris with no coauthors.

This ports the relevant tsgo behavior from the canonical typescript-go corpus into Home:

  • infers new Promise(...) payloads in TypeScript order: explicit type arguments, contextual Promise return/assignment targets, then resolver-value inference
  • synthesizes structural PromiseLike<T> and checks every nonempty executor resolve(value) against T | PromiseLike<T>
  • preserves the lexical IArguments type after the ES5 arrow diagnostic so Function.prototype.apply can enforce the source function parameter tuple
  • contextually checks tuple literals passed to .apply, including nonempty parameter tuples, without rejecting valid array literals

Exact movement

  • asyncAwaitNestedClasses_es5: fail -> pass
  • asyncArrowFunctionCapturesArguments_es5: fail -> pass
  • focused target batch: 0/2 -> 2/2 (+2, no regressions)
  • broad async exact slice: 148/149; only types.asyncGenerators.es2018.2 remains
  • projected full exact floor: 5326/5907 -> 5328/5907 (+2; full survey deferred until the next consolidated checkpoint)

Verification

  • focused async-helper checker tests: 3/3
  • exact target fixtures: 2/2
  • broad async exact slice: 148/149, with only the known async-generator mismatch

Delta: 1 file, 149 insertions, 19 deletions. The next chunk is the remaining async-generator protocol/yield diagnostic parity work.

14 days ago

Async generator protocol parity

Pushed d5fe7a55903b8a0a3e78705e30c40f84c1e52192 (fix(ts-checker): align async generator protocols).

This ports the remaining tsgo async-generator protocol behavior into Home:

  • tracks generator next contributions separately from yielded values, including tsgo-style any versus unknown inference;
  • accepts sync or async iterator protocols for async yield*, while reporting TS2504 for non-iterables;
  • preserves the Promise<T> wrapper for yield* Promise.resolve(...) protocol checks;
  • expands AsyncIterator<T> / Iterator<T> defaults in diagnostics;
  • reports precise yielded-element TS2322 diagnostics and operand anchors;
  • rejects async generators explicitly annotated with sync Iterable, Iterator, or IterableIterator protocols.

Parity movement:

  • types.asyncGenerators.es2018.2: 0/1 -> 1/1 exact
  • async exact slice: 148/149 -> 149/149
  • projected full exact floor: 5328/5907 -> 5329/5907
  • all 24 expected diagnostic headers in the target fixture now align

Verification:

  • focused async-generator checker tests: 10/10
  • exact target fixture: 1/1
  • exact async slice: 149/149

Change size: 1 file, 204 insertions, 24 deletions.

14 days ago

Generic thenable receiver parity

Pushed 3458d0a9549ff7d85c0a07b730995673f193b9a7 (fix(ts-checker): validate generic thenable receivers).

This ports the tsgo behavior behind await_incorrectThisType:

  • registers a generic class partial instance before member signatures are lowered, so static and instance self-references such as EPromise<E, never> retain their type arguments;
  • preserves discriminant literals for expression-bodied arrows with annotated generic-union returns;
  • models both optional PromiseLike.then callback parameters;
  • checks method receiver this through generic instance arguments instead of accepting a structurally hidden mismatch;
  • treats a callable then with an incompatible explicit this receiver as a malformed thenable under await.

Parity movement:

  • await_incorrectThisType: 0/1 -> 1/1 exact
  • projected full exact floor: 5329/5907 -> 5330/5907
  • restored both expected headers (TS2684 and TS1320)
  • removed four spurious headers (two TS2322, one TS2554, one TS2322/unknown assignment)

Verification:

  • focused generic-thenable checker test: 2/2
  • exact target fixture: 1/1
  • exact await slice: 87/87
  • generic-class checker slice: 14/14
  • PromiseLike checker slice: 2/2

Change size: 1 file, 91 insertions, 5 deletions.

14 days ago

Pushed 075058b57 (fix(ts-checker): infer complete JSX generic props) to main.

Parity movement:

  • Flipped checkJsxGenericTagHasCorrectInferences to exact pass.
  • Flipped tsxStatelessFunctionComponentsWithTypeArguments2 to exact pass.
  • Exact target slice: 0/2 -> 2/2.
  • Projected full-corpus floor: 5,330/5,907 -> 5,332/5,907.

What changed:

  • Ported staged tsgo JSX inference for annotated callbacks, ordinary attributes/spreads, and context-sensitive callbacks.
  • Preserved complete catch-all props through nested React managed-attribute intersections.
  • Combined same-named intersection props and validated callback return covariance.
  • Preserved generic spread constituents in whole-bag diagnostics (T & { ... }).
  • Defaulted genuinely uninferred JSX type parameters to declaration defaults or unknown.
  • Replaced the old bespoke unconstrained-spread diagnostic with tsgo-compatible whole-attributes TS2322 behavior.

Verification:

  • Focused JSX generic checker coverage: 7/7.
  • Exact upstream target fixtures: 2/2.
  • Broad exact jsx,tsx survey: 106/176; remaining misses align with the documented JSX/parser/runtime backlog.
  • Full checker suite: 3,272/3,275, with only the three intentional scratch probes failing (attrRes12, tuple ICA, attrRes15).
  • File delta: +482/-34 in packages/ts_checker/src/check.zig.

Commit: https://github.com/home-lang/home/commit/075058b57eb480ce59f1253f9f484862e7f5686f

14 days ago

Pushed f15b461cd (fix(ts-checker): resolve JSX managed class attributes) to main.

Parity movement:

  • Flipped tsxAttributeResolution12 to exact pass.
  • Flipped checkJsxChildrenCanBeTupleType to exact pass.
  • Flipped tsxAttributeResolution15 to exact pass.
  • Exact target slice: 0/3 -> 3/3.
  • Projected full-corpus floor: 5,332/5,907 -> 5,335/5,907.
  • Full checker suite: 3,272/3,275 -> 3,275/3,275; the three forced-failure scratch probes are now real passing regressions.

What changed:

  • JSX constructor-interface tags now prefer concrete managed props over inherited free generic signatures.
  • Qualified React subclasses inherit constructor overload counts, including synthetic react16.d.ts components.
  • In-source/synthetic IntrinsicClassAttributes<T> participates in class JSX targets, allowing ref callbacks.
  • Managed target rendering prunes nested {} constituents, orders class attributes like tsgo, and preserves ReactNode | undefined.
  • Top-level arrow this in an external module is modeled as undefined and reports the tsgo-compatible unnamed TS2532 on member writes.

Verification:

  • Focused JSX checker coverage: 54/54.
  • Exact upstream target fixtures: 3/3.
  • Full checker suite: 3,275/3,275.
  • File delta: +168/-157 in packages/ts_checker/src/check.zig.

Commit: https://github.com/home-lang/home/commit/f15b461cd69dba3b4156af525fda98be712c3c8c

14 days ago

JSX generic spread and constraint parity: +5 exact fixtures

Pushed c927b08348a36fc613acd08b796bcc935dd0bc28 (fix(ts-checker): align JSX generic spread inference) directly to main.

This batch ports the shared behavior behind tsgo's JSX generic inference rather than special-casing fixture names:

  • Preserves a bare generic JSX spread as its original inference candidate (T = U) even when an unconstrained U contributes no materialized object members, matching inferJsxTypeArguments and spread-type construction in internal/checker/jsx.go.
  • Finalizes inferred JSX type arguments against instantiated constraints and falls back to the constraint when a candidate violates it, matching getInferredType in internal/checker/inference.go.
  • Reuses a function declaration's already-lowered generic signature for JSX props, preserving declaration-scoped type parameters and constraints instead of re-lowering them as unknown at the use site.
  • Treats generic-spread attribute bags as non-fresh intersections for excess-property checks while retaining required-property and value checks.
  • Ignores every hyphenated JSX property during excess checking, matching tsgo's isIgnoredJsxProperty in internal/checker/relater.go.
  • Retains the IntrinsicAttributes & U mismatch, nested TS2322 chain, and TS2208 constraint hint for an unconstrained generic spread.
  • Anchors JSX TS2769 overload failures at the component tag, matching resolveJsxOpeningLikeElement/resolveCall.

Exact fixtures flipped from failing to passing:

  • tsxStatelessFunctionComponentsWithTypeArguments3
  • tsxStatelessFunctionComponentsWithTypeArguments4
  • tsxStatelessFunctionComponentsWithTypeArguments5
  • tsxStatelessFunctionComponentWithDefaultTypeParameter2
  • tsxGenericAttributesType8

Parity movement: projected exact floor 5,335/5,907 -> 5,340/5,907 (90.4%), leaving 567 exact fixtures.

Verification:

  • Focused checker regressions: 3/3
  • Focused exact conformance corpus: 5/5 (passed=5 failed=0)
  • Full ts_checker: 3,278/3,278
  • Checker scope: packages/ts_checker/src/check.zig, +319/-17

The broad -Dfilter=ts_conformance command still exits nonzero because of its existing unrelated standalone/category tests (genericCallWithGenericSignatureArguments, stringLiteralTypesAsTypeParameterConstraint02, and the baseline-aware type-relationship survey); the targeted exact corpus summary itself is fully green.

14 days ago

Published the JSX overload parity batch directly to main in two small conventional commits (authored/committed as Chris, no coauthors):

  • 4d9c70389 fix(ts-parser): retain bodyless rename diagnostics (+78/-2)
    • Retains TS2842/TS2843 for destructuring parameters in bodyless function/method signatures.
    • Retracts the likely-type-annotation diagnostic for implementations and ordinary arrow callbacks, avoiding object-rest regressions.
  • 6be82654f fix(ts-checker): align JSX overload applicability (+218/-86)
    • Ports concrete-spread overload applicability while preserving explicit excess checks for single class-props targets.
    • Accepts ignored hyphenated bags for zero-parameter candidates, but checks hyphenated properties when an overload explicitly declares them.
    • Resolves children props across overload candidates and contextually types callbacks in explicit attributes and spread object literals.
    • Defers overloaded value failures to TS2769 and anchors post-spread explicit failures at the offending attribute.

Exact fixtures flipped (4):

  • tsxStatelessFunctionComponentOverload1
  • tsxStatelessFunctionComponentOverload2
  • tsxStatelessFunctionComponentOverload3
  • tsxStatelessFunctionComponentOverload5

Parity movement:

  • 5340/5907 -> 5344/5907 exact fixtures
  • 90.47% exact parity
  • 563 remaining

Verification:

  • targeted exact overload cluster: 4/4
  • full ts_checker suite: 3279/3279
  • ts_parser target: pass
  • focused JSX overload regression: pass
  • existing concrete class-props spread regression: pass

Canonical upstream remains _submodules/typescript-go at b8276f35cd288aa163fad0516b60ddaacec87ee7, with .gitmodules tracking https://github.com/microsoft/typescript-go.git branch main (shallow).

14 days ago

Intrinsic JSX attribute parity: +5 exact fixtures

Pushed 5536d2b198efba37efa8e390077e6d304e956194 (fix(ts-checker): align intrinsic JSX attribute contracts) directly to main, authored and committed as Chris with no coauthors.

Ported behavior:

  • Lowercase intrinsic JSX tags remain namespace keys during structural diagnostics and are no longer evaluated as value-space identifiers, removing spurious TS2304 diagnostics for test1, test2, and div.
  • Explicitly valued optional boolean attributes preserve tsgo/tsc diagnostic targets such as boolean | undefined, while shorthand and optional string/number attributes retain their non-undefined target wording.
  • Required JSX prop validation recognizes inherited Object prototype members, so {} satisfies contracts such as { toString(): string }.
  • Overload prop lookup now follows the same intersection-aware JSX target helper used by direct props.

Exact fixtures flipped (5):

  • tsxAttributeResolution1
  • tsxAttributeResolution3
  • tsxAttributeResolution5
  • tsxAttributeResolution6
  • tsxAttributeErrors

Parity movement:

  • 5344/5907 -> 5349/5907
  • 90.55% exact parity
  • 558 remaining

Change size: packages/ts_checker/src/check.zig +55/-4 (59 lines).

Verification:

  • full ts_checker suite: 3280/3280
  • intended exact cluster: 5/5
  • combined attribute + prior overload regression set: all 15 intended fixtures pass; the runner reports 15/16 only because the substring filter for tsxAttributeResolution1 also captures the unrelated open tsxAttributeResolution16
  • focused intrinsic JSX structural regression: pass
14 days ago

Published 4615eada0 (fix(ts-checker): preserve JSX literal diagnostics) to main.

This ports the shared tsgo JSX elaboration behavior for fresh literals and spread overrides:

  • brace-expression values retain fresh numeric/boolean/string literals in TS2322 prose;
  • shorthand attributes retain the true literal;
  • quoted JSX strings still widen to string;
  • declared intrinsic hyphenated attributes defer to the synthesized whole-bag relation;
  • later object-literal spreads are inspected before mutable-location widening, preserving last-write-wins compatibility;
  • an any spread suppresses explicit value elaboration across the synthesized bag.

Exact flips: 4

  • tsxAttributeResolution7
  • tsxDefaultAttributesResolution3
  • tsxSpreadAttributesResolution10
  • tsxSpreadAttributesResolution11

Published parity floor: 5353/5907 (90.63%), 554 remaining (+4 from 5349).

Change size: 125 insertions / 19 deletions in packages/ts_checker/src/check.zig, including three focused regressions.

Verification:

  • checker suite: 3282/3282 passed
  • exact five-fixture JSX cluster: 4/5 passed
  • tsxSpreadAttributesResolution12 is behaviorally aligned and now differs only in whole-bag class-props target rendering/member order; that is the next isolated batch.
14 days ago

Published a255536c6 (fix(ts-checker): align JSX spread relation rendering) to main.

This closes the final fixture in the current JSX literal/spread cluster by porting two tsgo relation-display rules:

  • whole-bag class JSX value incompatibilities name the concrete managed-props constituent that owns the failing member (Prop), while missing/excess failures retain the full managed JSX intersection;
  • spread-property display order follows retained declaration identity/source position, while the actual relation bag keeps runtime last-write-wins construction.

Exact flip: tsxSpreadAttributesResolution12 (+1).

Published parity floor: 5354/5907 (90.64%), 553 remaining.

Change size: 79 insertions / 1 deletion in packages/ts_checker/src/check.zig, with a focused class-spread regression.

Verification:

  • focused JSX parity checker cases: 5/5 passed
  • tsxSpreadAttributesResolution12: 1/1 exact passed
  • all five fixtures touched by the two JSX commits pass exactly in the broader eight-fixture neighboring-class probe
  • parent checker suite: 3282/3282 passed

The neighboring tsxSpreadAttributesResolution2/5/6 failures are separate pre-existing missing-property, weak-type, and managed-intersection rendering gaps; they are the next logical class-spread diagnostic batch.

14 days ago

Published 884d006ae (fix(ts-checker): align class JSX spread diagnostics) to main.

This closes the neighboring class-component spread diagnostics by porting tsgo behavior for:

  • concrete props-constituent selection for TS2739/TS2741 missing-member elaboration;
  • recursive object-only managed-intersection normalization before JSX weak-target TS2559 selection;
  • grouped parenthesization for union-bearing managed props;
  • spread object-literal widening (mismatched string/number literals widen, matching contextual literals and booleans remain fresh);
  • shorthand source widening against non-literal targets while retaining true against literal targets.

Exact flips: 3

  • tsxSpreadAttributesResolution2
  • tsxSpreadAttributesResolution5
  • tsxSpreadAttributesResolution6

Published parity floor: 5357/5907 (90.69%), 550 remaining (+3 from 5354).

Change size: 230 insertions / 16 deletions in packages/ts_checker/src/check.zig, including two focused regressions and one corrected TS2739 unit expectation.

Verification:

  • exact target trio: 3/3 passed
  • expanded JSX cluster: 8/8 passed
  • focused JSX parity cases: 7/7 passed
  • complete JSX checker slice: 74/74 passed
  • consolidated checker run: 3284/3285 before correcting the sole stale TS2322/TS2353-only assertion; all other tests passed, and production logic was unchanged after that assertion-only fix.

Across today’s three JSX commits, the published exact floor moved +8 fixtures from 5349 to 5357.

14 days ago

Generic contextual callable parity: +5 exact fixtures

Pushed bcc2ebb1d (fix(ts-checker): align generic contextual callables) directly to main, authored and committed as Chris with no coauthors.

This ports the shared tsgo behavior behind the leading generic-callable failures:

  • context-sensitive arrows inherit generic contextual parameter types before their body return is checked;
  • generic function-expression implementations are erased per target overload for callable-object applicability while retaining construct/call kind and minimum arity;
  • callback return inference combines unrelated primitive covariant candidates without weakening object-member inference;
  • conditional callback returns retain fresh literal branches for constrained generic inference.

Exact fixtures flipped (5):

  • stringLiteralTypesAsTypeParameterConstraint02
  • genericContextualTypes1
  • genericCallWithGenericSignatureArguments
  • genericCallWithOverloadedFunctionTypedArguments
  • genericCallWithOverloadedFunctionTypedArguments2

Parity movement:

  • published exact floor: 5357/5907 -> 5362/5907 (90.77%)
  • remaining exact mismatches: 550 -> 545
  • leading exact window: 487/500 -> 492/500
  • change size: 121 insertions / 9 deletions in packages/ts_checker/src/check.zig, including three focused regressions

Verification:

  • targeted exact family plus regression sentinels: 10/10
  • complete leading 500-case exact window: 492/500, with precisely the eight pre-existing residual fixtures and no regressions
  • complete ts_checker suite: passed

The first broad draft exposed three over-permissive object-inference regressions; the final implementation confines primitive candidate unions to callback return inference, and all three sentinels (assignmentCompatWithCallSignatures3, assignmentCompatWithConstructSignatures3, and genericCallWithObjectLiteralArgs) are exact again.

14 days ago

Optional generic signature parity (+3 exact)

Pushed 91aa610d9 (fix(ts-checker): align optional generic signatures) directly to main.

Ported tsgo behavior

  • Canonicalize equal-arity generic signatures onto source declaration identities before relation checks.
  • Apply non-strict assignment bivariance while retaining strict heritage parameter checks.
  • Respect minimum required arity and optional T | undefined slots in generic call/construct properties.
  • Reject outer type parameters masquerading as target-owned generic parameters.
  • Compare generic arrow parameters independently from inferred returns during contextual applicability.
  • Widen nullish arrow returns to any when strictNullChecks is disabled.
  • Preserve declared generic parameter names in callable diagnostics.
  • Emit TS2695 once when contextual inference revisits a comma-bodied arrow.

Exact fixture movement

Flipped three fixtures with zero newly failing fixtures in a complete executable-to-executable failure-set comparison:

  • assignmentCompatWithGenericCallSignaturesWithOptionalParameters
  • subtypingWithGenericCallSignaturesWithOptionalParameters
  • subtypingWithGenericConstructSignaturesWithOptionalParameters

The reproducible pinned-corpus floor is 5,347/5,907 -> 5,350/5,907 (90.52% -> 90.57%), leaving 557. This audit corrects the previously stated 5,362 floor: the final pre-batch executable already contained all five fixtures attributed to bcc2ebb1d (focused overlap gate 7/7) but reproduces 5,347 against the pinned corpus. Current versus that exact binary has only the three pass flips above and no failure regressions.

Verification

  • Optional-generic checker regressions: 4/4
  • Contextual comma diagnostic regression: 2/2
  • Post-fix target/contextual exact gate: 4/4
  • Optional call/construct family: 7/7
  • Target plus heritage sentinels: 9/9
  • Leading exact window: 494/500
  • Full ts_checker: pass
  • Complete ts_conformance binary: 1,374/1,374
  • Complete exact corpus: 5,350/5,907

Change size: 228 insertions / 15 deletions in packages/ts_checker/src/check.zig, including four focused regression tests.

14 days ago

TS2411 index diagnostic parity (+2 exact)

Pushed 35eab6866 (fix(ts-checker): normalize index diagnostic types) directly to main.

Ported tsgo behavior

  • Normalize number | <numeric enum> index value types to number in TS2411 diagnostic rendering, matching tsgo union reduction.
  • Preserve source-written typeof f for both property declarations and index-signature value declarations.
  • Read the declaration-local type node instead of registering a display alias on a shared signature TypeId, avoiding cross-site diagnostic contamination.

Exact fixture movement

  • subtypesOfUnion
  • enumIsNotASubtypeOfAnythingButNumber

Both targets pass 2/2. The leading exact window advances 494/500 -> 495/500; the enum fixture is outside that window. Accumulated exact movement is +2, taking the reproducible floor from 5,350 toward 5,352/5,907 pending the next consolidated full audit.

Verification

  • Focused checker regression: 2/2
  • Exact target pair: 2/2
  • TS2411/index-signature neighborhood: 7/7
  • Leading exact window: 495/500
  • Full ts_checker: pass

Change size: 93 insertions / 8 deletions in packages/ts_checker/src/check.zig, including one regression covering property-side typeof, index-side typeof, and numeric-enum union normalization.

14 days ago

Forward generic constraint identity (e37736ceb)

Pushed fix(ts-checker): preserve forward constraint identity directly to main.

What moved

  • Logically flips typeParameterAssignability2.
  • Projected exact floor: 5352/5907 -> 5353/5907.
  • Projected leading-500 window: 495/500 -> 496/500.
  • These totals are intentionally marked projected until the next accumulated exact-corpus audit.

Root cause and port

Home already used a two-pass binder for function, class, and function-type parameters: pass one installed fresh placeholders so constraints could reference later parameters, then pass two created the finalized declaration TypeIds. Forward constraints retained the placeholder ids, however, so a chain such as T extends U, U extends V, V extends Date lost declaration identity after one edge. A name-based fallback hid direct cases but could not safely recover transitive chains.

The checker now records each placeholder-to-final declaration identity and dereferences it while reading constraints. Source-constraint assignability walks the chain recursively with a depth guard, matching tsgo’s getConstraintOfType(source) direction: T -> U -> V -> Date is accepted, while Date -> V, V -> U, and U -> T retain their arbitrary/different-subtype diagnostics. Distinct same-named type parameters in unrelated generic scopes are not conflated.

Size and validation

  • packages/ts_checker/src/check.zig: 96 insertions, 5 deletions.
  • Added a directional regression covering forward and reordered declarations: 12 valid ancestor assignments stay clean and exactly 12 reverse assignments retain TS2322.
  • Five focused checker invocations passed (10/10 compiled tests): the new chain regression, unrelated type parameters, sibling constrained parameters, variable initializers, and self-assignment.

The expensive exact corpus run remains deferred until several logical chunks have accumulated, per the batching strategy.

14 days ago

Private accessibility relation parity (d415d176c)

Pushed fix(ts-checker): preserve private member origins directly to main.

Fixture movement

  • assignmentCompatWithObjectMembersAccessibility: 44 emitted primary errors -> exact 24-error upstream matrix.
  • Logically flips one leading fixture.
  • Projected exact floor: 5353/5907 -> 5354/5907.
  • Projected leading-500 window: 496/500 -> 497/500.
  • Corpus totals remain projected until the next accumulated exact audit.

Root causes and port

  1. Assignment expressions eagerly reported a class-private structural mismatch, then the canonical checker relation rejected and elaborated the same assignment again. Removing the pre-report leaves one TS2322 per source assignment.
  2. Interfaces extending classes copy inherited private members with their original decl_node, but private compatibility required a class name for the enclosing object TypeId. Interface TypeIds have no class name, so Base and I extends Base were treated as separate private declarations while public/private relations through I were missed.
  3. Visibility prose used qualified bookkeeping names and the interface type instead of the private member’s declaration owner.

Private relation now compares the owning class declaration nodes first, with the existing ancestry lookup as fallback. This preserves nominal origin through class-derived and merged interfaces, including multiple inherited private bases. TS2325 naming uses the private member owner (Base/E) and the public compared type (I/D/anonymous shape), matching tsgo’s nested text without leaking namespace-qualified Home display metadata.

Size and validation

  • packages/ts_checker/src/check.zig: 115 insertions, 29 deletions.
  • Added an 18-error regression covering public interfaces, class-derived interfaces, same-origin assignments, public/private mismatches, separate private declarations, and unqualified nested prose.
  • Five focused checker invocations passed (10/10 compiled tests), including merged-interface private origins and inherited private access.
  • home-tsc rebuilt successfully.
  • Direct execution against the pinned upstream fixture emitted exactly 24 primary diagnostics, with matching TS2325/TS2442 nested messages.

The expensive full exact corpus remains deferred until the inference chunks below this leading window are accumulated.

14 days ago

Parity update: recursive mapped and intra-expression inference

Pushed cd93c1dcf (fix(ts-checker): align recursive intra-expression inference) to main.

Exact fixture flips

  • unionTypeInference now passes exact parity.
    • preserves literal 42 in the string & T -> never TS2345 diagnostic
    • suppresses the three false mapped-key TS2536 diagnostics
    • accepts the recursive DeepPromised<T> indexed specialization relation
    • reverse-infers Deep<T> through T[K] | Deep<T[K]>, removing the false baz(xx) TS2345
  • intraExpressionInferences now passes exact parity.
    • orders stable object members before callbacks with unfixed contextual parameters
    • carries inference through nested object spreads
    • rechecks block-bodied callbacks after substitutions and preserves explicit parameter annotations
    • re-instantiates mapped/conditional alias members from their original type syntax
    • emits the expected TS2322 for the map callback and TS2339 for inputs.nonexistent
    • avoids regressions in Chain, Opts, predicate, nested-consumer, and value-returning-to-void cases
  • intraExpressionInferencesJsx remains exact-green.

Movement

Projected exact floor: 5354/5907 -> 5356/5907 (+2 fixtures), leaving 551 remaining.

Change size

  • packages/ts_checker/src/check.zig: 617 insertions, 19 deletions

Validation

  • focused checker regression: recursive homomorphic/union inference passed
  • focused checker regression: intra-expression object members and spreads passed
  • direct strict compilation of intraExpressionInferences.ts produced only its two expected diagnostics
  • exact corpus filter unionTypeInference,intraExpressionInferences: unionTypeInference and the JSX sibling passed; the first pass exposed over-eager contextual rechecks
  • exact corpus filter intraExpressionInferences after narrowing: 2/2 passed (intraExpressionInferences plus JSX sibling)

Next leading-500 target: unionAndIntersectionInference1 (definite assignment, zero-argument Promise.resolve, and Object.assign overload inference).

14 days ago

Published 190039b34 (fix(ts-checker): align builtin intersection inference) to main.

This closes exact fixture unionAndIntersectionInference1 from 0/1 to 1/1 by porting the remaining tsgo semantics as one coherent batch:

  • definite-assignment tracking now distinguishes explicit undefined from void, restoring TS2454 for T | void while preserving the T | undefined exemption;
  • Promise.resolve now exposes both zero- and one-argument overloads;
  • the checker models the generic Object.assign<T extends {}, U> overload, its {} / object constraint failures, TS2769 chain and related TS2208 hints, and the first-overload recovery return used by downstream inference;
  • relation logic now treats only synthetic __call / __construct slots as an object own callable surface, so a function-valued property no longer makes its enclosing object callable;
  • callable intersection diagnostics render from the written annotation, preventing unused generic signature metadata from leaking <T> into a non-generic () => void target.

Measured validation:

  • 4 focused checker/relation regressions pass;
  • exact unionAndIntersectionInference1 passes 1/1, with all 8 diagnostic headers aligned;
  • implementation delta: 327 insertions, 8 deletions across checker and relation logic.

Parity movement is projected at 5,356/5,907 -> 5,357/5,907, leaving 550 exact fixtures. The leading-500 window is projected 499/500 -> 500/500; a consolidated exact leading-500 audit is next to replace that projection with a measured result.

14 days ago

Fresh-cache correction to the projection above: the consolidated exact leading-500 audit at 190039b34 measured 497/500, not 500/500. The earlier 499/500 floor had been assembled from focused deltas rather than a fresh full-window run, and Zig cached the first attempted audit; rerunning with a fresh local cache exposed three remaining fixtures:

  • everyTypeAssignableToAny: one extra TS2454 at the g binding after the void definite-assignment change;
  • genericCallWithObjectTypeArgsAndConstraints3: one missing TS2741 for Derived2 against Derived;
  • narrowingGenericTypeFromInstanceof01: one extra TS2345 after generic instanceof narrowing.

The published fixture flip remains valid: unionAndIntersectionInference1 is independently measured 1/1. I am treating 497/500 as the current measured leading-window baseline and batching the three remaining semantic fixes next.

14 days ago

Leading 500 exact parity reached

Pushed 35fdcab0b (fix(ts-checker): align leading generic inference parity) directly to main.

This flips the final three failures from the corrected leading-window baseline:

  • everyTypeAssignableToAny: direct void declarations are initialized for definite-assignment purposes, while T | void remains subject to TS2454.
  • genericCallWithObjectTypeArgsAndConstraints3: repeated object-constrained generic property occurrences now share the declared inference binding, producing the expected TS2741 for the later incompatible sibling while preserving the deferred U extends { x: T; y: T } calls.
  • narrowingGenericTypeFromInstanceof01: instanceof preserves the exact A<T> union constituent for classes whose private member is introduced by a constructor parameter property.

Measured parity movement: 497/500 -> 500/500 exact fixtures, with all three failures flipped and no remaining failures in the leading window.

Validation on the committed source state:

  • 3 focused checker regressions passed.
  • 7/7 exact intended-plus-regression fixtures passed, including unionAndIntersectionInference{1,2,3} and unionTypeInference after narrowing the inference fix.
  • A fresh-cache leading corpus audit passed 500/500 (failed=0, skipped=0).

Implementation delta: 123 insertions, 11 deletions in packages/ts_checker/src/check.zig. The first broad identity-normalization attempt was rejected after a fresh audit exposed four union-inference regressions (496/500); the shipped implementation is restricted to repeated direct object members sharing one object-constrained declared parameter.

14 days ago

Published 66573e756 (fix(ts-checker): align enum and constructor recovery) directly to main as Chris, with no coauthor.

This batch ports four related tsgo behaviors:

  • numeric-enum unions containing broad number now share one normalization predicate for assignability and TS2411 rendering; this preserves enum identity while treating e | number as broad number where upstream does
  • inaccessible private/protected constructor calls now resolve through the error-call recovery type (any), suppressing secondary arity and constructor assignment diagnostics exactly as tsgo does
  • class-field duplicate binding now reports every declaration after the first canonical numeric key, including 1, 1.0, 1., and 1.00
  • focused regressions cover numeric enum targets, TS2411 text, inaccessible constructor recovery, and 4-way numeric field collisions

Exact parity movement:

  • fixtures 1-500: 500/500 -> 500/500 (no regression)
  • fixtures 501-1000: 424/500 -> 428/500
  • failures in the second window: 76 -> 72
  • net: +4 exact fixtures

Flipped exact fixtures:

  • unionSubtypeIfEveryConstituentTypeIsSubtype
  • typesWithPrivateConstructor
  • typesWithProtectedConstructor
  • objectTypeWithDuplicateNumericProperty

Verification:

  • 4 focused checker regressions passed
  • all 4 targeted exact baselines passed on the final combined implementation
  • fresh leading 500 audit passed 500/500
  • fresh 501-1000 audit passed 428/500

Change size: 112 insertions / 25 deletions in packages/ts_checker/src/check.zig.

Next I am clustering the remaining second-window failures around callable subtyping/contextual diagnostic anchoring and type-parameter constraint relations, prioritizing shared semantic fixes that can flip multiple fixtures.

14 days ago

Published 189db71a4 (fix(ts-checker): align callback and noLib diagnostics) to main.

Parity movement

  • Exact 501-1000 window: 428/500 -> 432/500 (+4 fixtures, 68 remaining).
  • Leading 1-500 regression guard remains 500/500.
  • Targeted intended + adjacent fixture audit: 6/6.

Flipped fixtures

  • subtypingWithCallSignaturesA
  • libReferenceNoLib
  • libReferenceNoLibBundle
  • missingDecoratorType

Implementation details

  • Recovered annotated expression-bodied callback diagnostics at the call argument boundary, matching tsgo's TS2345 placement instead of retaining an eager inner TS2322.
  • Made noLib suppress reference-lib DOM loading so local declarations win, while preserving the opposite precedence for explicit /// <reference lib="dom" preserve="true" /> under an ES-only lib selection.
  • Matched required noLib global selection when the core global set is supplied, including decorator-specific TypedPropertyDescriptor behavior.
  • Sorted pathless/global diagnostics by TypeScript code in both conformance execution paths, so TS2318 precedes TS5107 regardless of hidden source position.

Regression checks

  • libReferenceDeclarationEmit and libReferenceDeclarationEmitBundle were explicitly retained after the DOM precedence refinement.
  • Fresh unique Zig caches were used for targeted and 500-fixture audits to avoid environment-filter cache reuse.

Change size: 195 insertions, 3 deletions across 2 files.

14 days ago

Published 57394cea0 (fix(ts-checker): align contextual and object rest parity) to main.

Parity movement

  • Exact 501-1000 window: 432/500 -> 435/500 (+3 fixtures, 65 remaining).
  • Leading 1-500 regression guard remains 500/500.
  • Targeted intended + adjacent fixture audit: 4/4.

Flipped fixtures

  • contextualTypeWithUnionTypeMembers
  • contextuallyTypedStringLiteralsInJsxAttributes01
  • objectRestNegative

Implementation details

  • Contextual callback parameter lookup now unwraps annotated array element types before resolving object-literal members, so union-only members inside array element objects receive their callable context instead of TS7006.
  • JSX mismatch elaboration preserves quoted string literals when the target prop is a string-literal union, matching the same contextual literal behavior already used for braced expressions.
  • Object-rest assignment now builds the residual source shape by omitting properties preceding the final rest, then checks that shape against identifier/member/element rest targets. Binding and assignment residual construction share the same member-filtering logic.
  • Invalid patterns with an earlier non-final rest stop after TS2462 and do not emit follow-on residual assignment diagnostics.

Regression checks

  • objectRestPropertyMustBeLast remains exact after adding the invalid-pattern suppression.
  • Fresh exact windows used unique Zig caches: 435/500 for fixtures 501-1000 and 500/500 for fixtures 1-500.

Change size: 99 insertions, 19 deletions in 1 file.

14 days ago

TS parity: ambient import-type resolution

Published cc3567ce8 (fix(ts-checker): align ambient import type parity) directly to main.

What changed

  • Resolve qualified import-type paths through matching ambient modules, so import("foo2").Bar.I sees namespace members merged with an ambient class declaration.
  • Suppress TS2693 at the final diagnostic boundary when an identifier is the target of export =, including type-only interface targets.
  • Skip the parser synthetic unknown root for bare generic import types after an export = assignment has established the module type.
  • Added focused checker regressions for all three behaviors.

Exact parity movement

  • Fixtures 501-1000: 435/500 -> 438/500 (+3 exact passes, failures 65 -> 62)
  • Fixtures 1-500: 500/500, unchanged
  • Flipped fixtures:
    • importTypeGenericTypes
    • importTypeAmbient
    • importTypeAmbientMissing

Verification

  • Targeted exact upstream audit: 3/3
  • Focused checker regressions: 3/3
  • Exact fixtures 501-1000 guard: 438/500
  • Exact fixtures 1-500 guard: 500/500

Change size

  • packages/ts_checker/src/check.zig: 78 insertions, 0 deletions
  • Commit author and committer: Chris <chrisbreuer93@gmail.com>
  • No coauthor trailers.

Sign in to comment on this issue.