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

TS parity: typesVersions export-star back-references

Published 489407d36 (fix(ts-resolver): follow explicit export-star back-references) directly to main.

What changed

  • Added shared cross-file export-fact resolution in ts_program for explicit relative export * subpaths.
  • Preserved mapped package-entry behavior for directory/index back-references such as export * from "../", which must remain unresolved in this fixture.
  • Followed explicit leaf back-references such as export * from "../other", exposing fb from the original declaration file.
  • Wired the shared facts into both the conformance resolver adapter and production home tsc CLI adapter.
  • Kept the checker virtual-section fallback behavior aligned and added focused regressions at checker and resolver levels.

Exact parity movement

  • Fixtures 501-1000: 438/500 -> 439/500 (+1 exact pass, failures 62 -> 61)
  • Fixtures 1-500: 500/500, unchanged
  • typesVersions family: 7/8 -> 8/8
  • Flipped fixture: typesVersionsDeclarationEmit.multiFileBackReferenceToSelf

Verification

  • Exact targeted upstream fixture: 1/1
  • Exact typesVersions family: 8/8
  • Full ts_program package tests: pass
  • Exact fixtures 501-1000 guard: 439/500
  • Exact fixtures 1-500 guard: 500/500

Change size

  • 4 files: 159 insertions, 5 deletions
  • Commit author and committer: Chris <chrisbreuer93@gmail.com>
  • No coauthor trailers.
14 days ago

Published 9805b5211 (fix(ts-checker): align switch and JSX spread parity) to main as Chris, with no coauthor trailers.

What moved

Ported two shared tsgo behaviors into the Home checker:

  • switch case expressions now participate in TS2454 definite-assignment flow for typed variables; switch discriminants that reduce from disjoint primitive intersections to never no longer produce spurious TS2678 comparability errors
  • JSX overload applicability now keeps explicit attributes fresh beside concrete spreads while preserving the indeterminate behavior of generic spreads; post-spread structural failures also use tsgo-compatible explicit-attribute anchors

Added focused regressions covering typed switch case reads, disjoint union comparability retention, concrete JSX spread excess properties, and TS2769 tag-vs-attribute anchors. Checker delta: +115/-9.

Exact parity movement

  • targeted fixtures: 0/3 -> 3/3
    • switchCaseWithIntersectionTypes01
    • switchCaseWithUnionTypes01
    • contextuallyTypedStringLiteralsInJsxAttributes02
  • fixtures 501-1000: 439/500 -> 442/500 (+3, 58 failures remain)
  • fixtures 1-500: 500/500, unchanged

Validation

  • focused switch checker tests: 18/18
  • focused JSX overload checker tests: 3/3
  • targeted exact conformance run: 3/3
  • leading exact guard: 500/500
  • second exact window: 442/500

The remaining 58 failures in the second window are now the inventory for the next shared-semantics batch.

14 days ago

Published 9370a0ceb (fix(ts-checker): check signature constraint cycles) to main as Chris, with no coauthor trailers.

What moved

Anonymous call and construct signatures now run the same type-parameter declaration checks already used by classes, interfaces, functions, aliases, and arrows. This ports tsgo-compatible TS2313 detection for direct and mutual circular constraints in object type signatures. A node-level dedupe guard prevents repeated lowering paths from emitting the same cycle diagnostic more than once.

Added a focused regression covering a direct call-signature cycle and a mutual construct-signature cycle. Checker delta: +17/-2.

Exact parity movement

  • targeted fixtures: 0/2 -> 2/2
    • typeParameterDirectlyConstrainedToItself
    • typeParameterIndirectlyConstrainedToItself
  • fixtures 501-1000: 442/500 -> 444/500 (+2, 56 failures remain)
  • fixtures 1-500: 500/500, unchanged

Validation

  • focused circular type-parameter tests: 3/3
  • targeted exact conformance run: 2/2
  • leading exact guard: 500/500
  • second exact window: 444/500

This follows the earlier switch/JSX batch in the same parity issue and keeps the remaining second-window inventory at 56 exact failures.

14 days ago

Published d7d5afa13 (fix(ts-checker): infer class constructor arguments) to main as Chris, with no coauthor trailers.

What moved

Generic class constructor inference now participates in constructor applicability, not only in the resulting instance type. For omitted class type arguments, Home now:

  • infers substitutions from constructor arguments
  • normalizes inferred candidates against the class type-parameter constraints
  • substitutes those parameters into the constructor signature before overload/argument validation
  • reuses the same normalized substitutions when instantiating the resulting class type

This removes the false TS2345 on a valid new C({ length: 2 }) while retaining a real constraint failure such as new C<number-like violation> through the normalized fallback. The existing wrapped-constraint regression now asserts exactly one legitimate downstream error instead of merely checking that some TS2345 exists. Checker delta: +61/-9.

Exact parity movement

  • targeted fixture: 0/1 -> 1/1
    • wrappedAndRecursiveConstraints4
  • fixtures 501-1000: 444/500 -> 445/500 (+1, 55 failures remain)
  • fixtures 1-500: 500/500, unchanged

Validation

  • focused constructor-inference tests: 2/2
  • targeted exact conformance run: 1/1
  • leading exact guard: 500/500
  • second exact window: 445/500
14 days ago

Literal alias diagnostic parity

Published a9656cc9c (fix(ts-checker): render reduced literal alias diagnostics) to main.

This batch fixes diagnostic rendering for generic aliases that reduce to a single property-key literal. The checker was already materializing KeysExtendedBy<M, number> as the concrete key "b", but TS2345 fell back to the alias display name instead of the surviving literal. The formatter now renders singleton property-key targets directly from their literal payload.

The first guard pass exposed a related flag-model edge: union/intersection flags OR-fold member flags, so a literal union can also carry is_literal. Sending that container through the scalar literal payload reader produced an unrelated literal. The shared scalar literal renderer now rejects union/intersection containers and leaves them to the structural literal-union renderer.

Parity movement:

  • flipped mappedTypeAsClauses
  • fixtures 501-1000: 445/500 -> 446/500 (54 remain)
  • fixtures 1-500: held at 500/500
  • exact regression audit: 3/3 (mappedTypeAsClauses, templateLiteralTypes4, typeArgumentsWithStringLiteralTypes01)

Verification:

  • 4 focused checker regressions passed, including new singleton-remap and numeric-literal-union tests
  • fresh first-window guard: 500/500
  • fresh second-window guard: 446/500

Diff: 40 insertions, 1 deletion in packages/ts_checker/src/check.zig.

Authorship was verified as Chris <chrisbreuer93@gmail.com> for both author and committer, with no co-author trailers.

14 days ago

TS2367 flow reachability parity

Published 52ff15a92 (fix(ts-checker): respect no-overlap flow reachability) to main.

This batch aligns TS2367 emission with tsgo control flow for no-overlap equality chains. Home already knew I1 & I3 and I2 had no comparable overlap, but emitted TS2367 throughout the entire if / else if chain. tsgo reports the two initial strict-equality comparisons and the first strict-inequality comparison; that inequality is provably true, making its || RHS and later else if conditions unreachable for TS2367.

The checker now:

  • derives constant equality results from the existing comparable-overlap relation
  • composes those results through && / || short-circuiting
  • walks logical and if ancestry before reporting TS2367
  • suppresses only the no-overlap diagnostic on unreachable paths while continuing to type-check all expressions for other errors

Parity movement:

  • flipped equalityWithIntersectionTypes01
  • fixtures 501-1000: 446/500 -> 447/500 (53 remain)
  • fixtures 1-500: held at 500/500
  • exact audit: 1/1

Verification:

  • new no-overlap short-circuit regression passed
  • all 13 existing TS2367-focused checker tests passed
  • fresh first-window guard: 500/500
  • fresh second-window guard: 447/500

Diff: 90 insertions, 0 deletions in packages/ts_checker/src/check.zig.

Authorship was verified as Chris <chrisbreuer93@gmail.com> for both author and committer, with no co-author trailers.

14 days ago

Published 093159cd6 (fix(ts-checker): align object rest assignment diagnostics) to main.

This flips objectRest by aligning both object-rest diagnostic paths with tsgo:

  • object binding declarations with a rest capture no longer run the fresh object-literal excess-property check against only the named binding shape (var { x, ...fresh } = { x: 1, y: 2 } now stays clean)
  • object-rest assignment targets reached through dynamic computed keys now elaborate the residual {} mismatch as TS2739 and list a, b, instead of falling back to generic TS2322
  • strengthened the residual assignment regression to assert the exact upstream TS2739 message
  • corrected a dormant focused-test setup typo discovered while compiling the complete object-rest slice

Parity movement:

  • fixtures 1-500: 500/500 retained
  • fixtures 501-1000: 447/500 -> 448/500
  • second-window failures remaining: 52
  • exact objectRest family: 10/10

Verification:

  • 12/12 focused object-rest checker tests
  • fresh exact first-window guard: 500/500
  • fresh exact second-window guard: 448/500
  • git diff --check clean

Change size: +56/-8 lines in packages/ts_checker/src/check.zig. Commit author and committer are Chris <chrisbreuer93@gmail.com> with no coauthor trailers.

14 days ago

Published 43bb3a68c (fix(ts-checker): accept callable Function constraints) to main.

This ports the builtin Function constraint relation across all checker surfaces that validate a generic candidate:

  • ordinary argument assignability
  • inferred generic substitutions
  • explicit type arguments
  • constrained type parameters, including chained constraints
  • callable interfaces and call signatures
  • construct signatures and class constructor values
  • callable unions (all members) and intersections (a callable constituent)

The rule is target-specific: ordinary callable-signature constraints remain strict, and number/plain-object arguments still fail.

Parity movement:

  • flipped functionConstraintSatisfaction
  • fixtures 1-500: 500/500 retained
  • fixtures 501-1000: 448/500 -> 449/500
  • second-window failures remaining: 51
  • exact functionConstraintSatisfaction family: 2/3; fixture 2 is now isolated to negative diagnostic rendering and arity suppression

Verification:

  • focused checker regression covering inferred and explicit calls, callable/constructable values, constrained forwarding, and three negative controls
  • fresh exact first-window guard: 500/500
  • fresh exact second-window guard: 449/500
  • git diff --check clean

Change size: +67/-0 lines in packages/ts_checker/src/check.zig. Commit author and committer are Chris <chrisbreuer93@gmail.com> with no coauthor trailers.

14 days ago

Published b60ac9b5e (fix(ts-checker): align Function constraint failures) to main.

This closes the negative half of builtin Function constraint parity:

  • suppresses redundant TS2345 constraint elaboration when the call already fails with too-many-arguments TS2554
  • rejects broad Function and interfaces extending Function as sources for a specific call signature
  • preserves builtin-object and single-base provenance when object types are substituted
  • renders Function, typeof C, construct signatures, derived interfaces, and constrained T/U sources with upstream TS2345 prose
  • types new Function() as the builtin Function instance instead of any
  • retains TS2558 validation for explicit type arguments on new Function<T>()

Parity movement:

  • flipped functionConstraintSatisfaction2
  • fixtures 1-500: 500/500 retained
  • fixtures 501-1000: 449/500 -> 450/500
  • second-window failures remaining: 50
  • exact functionConstraintSatisfaction family: 3/3

Verification:

  • 3/3 focused Function-constraint checker tests, including positive and negative matrices
  • fresh exact family run: 3/3
  • fresh exact first-window guard: 500/500
  • fresh exact second-window guard: 450/500
  • git diff --check clean

Change size: +140/-4 lines in packages/ts_checker/src/check.zig. Commit author and committer are Chris <chrisbreuer93@gmail.com> with no coauthor trailers.

14 days ago

Published a252c1fe5 (fix(ts-checker): follow subtype constraint chains) to main.

This parity chunk makes heritage assignability recurse through source type-parameter constraints until concrete bounds are reached, and preserves compatible repeated var declarations when conditional inference swaps a polymorphic this type with another type parameter.

Parity movement:

  • flipped 2 TypeScript conformance fixtures
  • subtypesOfTypeParameter family: 6/6 passing
  • fixtures 1-500: 500/500 passing
  • fixtures 501-1000: 450 -> 452/500 passing (48 remaining)

Verification:

  • 2 focused checker regression tests
  • exact six-fixture subtype family survey
  • fresh first-window exact survey: 500/500
  • fresh second-window exact survey: 452/500

Change size: +57/-2 lines, checker only. Commit author and committer are Chris <chrisbreuer93@gmail.com> with no coauthor trailers.

14 days ago

Published 2ff91a405 (fix(ts-checker): resolve constrained property access) to main.

This chunk resolves dot and bracket access through complete type-parameter constraint chains while preserving direct generic receiver names in TS2339 diagnostics. Uninferred constrained generic calls now fall back to their concrete base constraint, chained generic return checks use the concrete object bound, and any + any remains any without changing any + number callback inference.

Parity movement:

  • flipped 2 TypeScript conformance fixtures
  • propertyAccessOnTypeParameter family: 6/6 passing
  • fixtures 1-500: 500/500 passing
  • fixtures 501-1000: 452 -> 454/500 passing (46 remaining)

Verification:

  • 8 focused constrained checker tests, including 2 new regressions
  • exact target plus literalTypes2 regression batch: 3/3
  • exact six-fixture property-access family survey: 6/6
  • fresh first-window exact survey: 500/500
  • fresh second-window exact survey: 454/500

The first guard initially caught an extra literalTypes2 TS2322 from an over-broad any + number rule. The implementation was narrowed to the required any + any case, a focused g8(1, x => x + 1) regression was added, and both exact/full guards were rerun cleanly.

Change size: +74/-7 lines, checker only. Commit author and committer are Chris <chrisbreuer93@gmail.com> with no coauthor trailers.

14 days ago

Published 32d8a59e1 (fix(ts-checker): align generic null assertions) to main.

What changed

  • Restricted null assertion permissiveness to a bare unconstrained type parameter. Constrained type parameters, generic arrays, and concrete object targets now correctly report TS2352 under strict null checks.
  • Preserved namespace-local assertion diagnostic display (Base inside namespace Errors, rather than Errors.Base).
  • Suppressed the contextual arrow return TS2322 cascade when the failed assertion already emitted primary TS2352.
  • Suppressed TS2352 when the assertion target already has a generic arity diagnostic (TS2314/TS2707), preserving upstream diagnostic precedence for <C>null and <M.E>null.
  • Added focused regressions for constrained/generic-array assertions, namespace-local type display, contextual return cascades, and missing generic arguments.

Exact parity movement

  • Flipped subtypingWithCallSignatures2 and subtypingWithCallSignatures3: +2 fixtures.
  • Full subtypingWithCallSignatures* family: 8/8.
  • Neighboring generic-arity regression filter (including .d.ts and ...3 substring neighbors): 6/6.
  • Fixtures 1-500: 500/500.
  • Fixtures 501-1000: 454/500 -> 456/500, leaving 44 in this window.

Patch and verification

  • Checker source delta: +112/-15.
  • Focused Zig checker regressions passed.
  • Fresh exact conformance runner was built once and reused for the family and both 500-fixture windows.
  • Commit author/committer: Chris <chrisbreuer93@gmail.com>; no coauthor trailers.

Next: batch the remaining 44 failures by shared checker subsystem and continue landing small, independently verified parity commits.

14 days ago

Published 6224d9cad (fix(ts-checker): relate mapped types to open indexes) to main.

What changed

  • Homomorphic mapped sources such as Partial<T> and Readonly<T> now satisfy a pure { [key: string]: any } target when that target has no required named members.
  • The same structural rule is used by ordinary assignment and interface heritage relations, so a generic override like value: Partial<T> no longer emits a spurious TS2430 against a base value: { [key: string]: any }.
  • Structured targets with required named members remain on the normal relation path.
  • Added focused coverage for both assignment forms and the generic interface override.

Exact parity movement

  • Flipped mappedTypesAndObjects: +1 fixture (all three diagnostic mismatches removed by the shared rule).
  • Focused exact fixture: 1/1.
  • Fixtures 1-500: 500/500.
  • Fixtures 501-1000: 456/500 -> 457/500, leaving 43.

Patch and verification

  • Checker source delta: +30/-0.
  • Focused checker regression passed.
  • Fresh exact runner reused for the target and both broad windows.
  • Commit author/committer: Chris <chrisbreuer93@gmail.com>; no coauthor trailers.

Next: continue through the measured low-delta mapped/keyof failures before taking on the larger relation-engine clusters.

14 days ago

Published 31b574d38 (fix(ts-checker): contextually type indexed callbacks) to main.

What changed

  • Function values assigned through element access are now contextually checked when the write target has exactly one callable signature.
  • Callable unions/intersections are also valid context only when every branch agrees on parameter types, rest shape, and minimum arity; incompatible callable sets remain uncontextualized.
  • Seeded Window.resizeBy(x: number, y: number): void and Window.resizeTo(width: number, height: number): void from upstream dom.generated.d.ts.
  • This preserves callback parameter context for window[action] = (x, y) => ... where action comes from the const tuple resizeTo | resizeBy, removing the two spurious TS7006 diagnostics.
  • Added a focused checker regression mirroring that exact loop.

Exact parity movement

  • Flipped keyofAndIndexedAccess2: +1 fixture.
  • Focused exact fixture: 1/1.
  • Fixtures 1-500: 500/500.
  • Fixtures 501-1000: 457/500 -> 458/500, leaving 42.

Patch and verification

  • Checker source delta: +64/-1.
  • Focused checker regression passed.
  • Fresh exact runner reused for the target and both broad windows.
  • Commit author/committer: Chris <chrisbreuer93@gmail.com>; no coauthor trailers.

Next: continue through the remaining low-delta mapped and recursive relation failures, then take the larger union/rest clusters as dedicated batches.

14 days ago

Recursive generic expansion parity: 6dea038a2

Published fix(ts-checker): reject expanding generic objects to main as Chris, with no coauthor trailers.

What changed

  • Added a bounded object-member relation guard for the tsgo infinite-expansion case.
  • When a target property is a bare type parameter T, a source property cannot satisfy it by recursively expanding to an object that contains that same T.
  • Restricted the guard to ordinary object-to-object relations. Signatures, unions, intersections, this parameters, and identical member types keep their existing relation paths.
  • Added a checker regression covering both OwnerList<string> -> List<string> and OwnerList<T> -> List<T>; both now produce TS2322.
  • Change size: +78/-0 in packages/ts_checker/src/check.zig.

Exact parity movement

  • Flipped infiniteExpansionThroughInstantiation.
  • Fixtures 1-500 remain 500/500.
  • Fixtures 501-1000 advance 458/500 -> 459/500.
  • The second window now has 41 known failures.
  • Current published first-1000 total: 959/1000.

Validation

  • Focused checker regression: 2/2 passed.
  • Fresh exact target filter: 2/2 passed (the filter also selects the sibling fixture).
  • Targeted collateral screen: 11/11 passed, including every first-window fixture affected by the initially broader prototype.
  • Fresh exact aggregate windows: 500/500 and 459/500.
  • git diff --check: clean.

The implementation is aligned against tsgo main at b8276f35cd288aa163fad0516b60ddaacec87ee7. Next work continues through the remaining recursive aliases and mapped/keyof relation failures in the second window.

14 days ago

Mapped grammar and diagnostics batch: 51e41ad5e

Published fix(ts): classify mapped member syntax to main as Chris, with no coauthor trailers.

What changed

  • Parser now recognizes [K in Keys] mapped syntax when it follows an ordinary type member and when it appears in an interface.
  • Invalid mapped bodies consistently use TS7061 and no longer leak TS1169/TS1170 computed-property diagnostics.
  • Class members distinguish type-only mapped syntax from real computed in expressions:
    • [K in Keys], where Keys is a type alias, emits TS7061 plus the expected emit-time TS2304/TS2693 diagnostics.
    • [K in "a" | "b"] remains an ordinary computed property and preserves TS1166/arithmetic diagnostics.
  • Generic mapped initializer failures now render the written source and target names, such as Type 'T' is not assignable to type 'Modify<T>'., and anchor at the declared variable name.
  • Change size: +138/-9 across packages/ts_parser/src/ts_parser.zig and packages/ts_checker/src/check.zig.

Exact parity movement

  • Flipped mappedTypeAsClauseRelationships.
  • Flipped mappedTypeProperties.
  • Fixtures 1-500 remain 500/500.
  • Fixtures 501-1000 advance 459/500 -> 461/500.
  • The second window drops from 41 -> 39 failures.
  • Current published first-1000 total: 961/1000.

Validation

  • Parser TS7061 focus: 6/6 passed.
  • Mapped declaration checker focus: 2/2 passed.
  • Mapped class grammar checker focus: 2/2 passed.
  • Fresh exact upstream fixture batch: 2/2 passed.
  • Fresh exact aggregate windows: 500/500 and 461/500.
  • git diff --check: clean.

The implementation remains aligned against tsgo main at b8276f35cd288aa163fad0516b60ddaacec87ee7. Next work stays in the mapped cluster, focusing on homomorphic array/tuple materialization and mapped relation semantics.

14 days ago

Homomorphic mapped arrays instantiated with any

Published a23556340 (fix(ts-checker): materialize homomorphic mapped arrays).

This ports tsgo declaration-site handling for homomorphic mapped types such as { [K in keyof T]: T[K] } when instantiated with any:

  • array- or tuple-constrained source parameters now materialize an array with the mapped numeric element type;
  • unconstrained mappings remain object mappings;
  • indirect aliases preserve the declaration that actually owns the mapped type, so an outer array constraint does not incorrectly force an array;
  • mapped optional and readonly modifiers are retained;
  • direct and memoized alias display names remain stable for exact diagnostics;
  • genuine array origins are tracked separately from structural array-like interfaces, producing canonical TS2740 missing-array-member diagnostics without regressing custom index-signature objects;
  • typed call results are still checked when the call receives an any argument.

Parity movement:

  • mappedTypeWithAny: failing -> passing
  • first survey window: 500/500
  • second survey window: 461/500 -> 462/500
  • exact regression set: 3/3 for mappedTypeWithAny, assignFromStringInterface2, and unionTypeIndexSignature
  • focused checker tests: 2/2

Change size: +207/-6 in packages/ts_checker/src/check.zig.

14 days ago

Generic mapped modifier relations

Published d10d2fa25 (fix(ts-checker): order mapped modifiers in relations).

This replaces the identity-only mapped relation shortcut with the tsgo relation model:

  • compare combined mapped optionality using -? < unchanged < +?, including optionality inherited through homomorphic operands and uniform intersections;
  • relate target key constraints to source key constraints contravariantly;
  • substitute the source mapped key parameter into the target key context;
  • compare mapped value templates covariantly, including NonNullable<T[P]> intersections;
  • deeply substitute through keyof, indexed-access, conditional, and nested mapped types;
  • allow required/readonly mapped sources to flow back to their source type parameter while keeping partial sources rejected;
  • reject empty objects for non-partial generic mapped targets;
  • preserve synthesized utility aliases such as Required<Foo> in missing-property diagnostics.

Parity movement:

  • mappedTypes6: failing -> passing
  • first survey window: 500/500
  • second survey window: 462/500 -> 463/500
  • remaining second-window failures: 37, unchanged except for mappedTypes6 closing
  • exact mapped regression set: 6/7; only the pre-existing mappedTypeRelationships diagnostic-shape fixture remains open
  • focused relation and alias-display tests: 2/2 each

Change size: +256/-24 across packages/ts_checker/src/check.zig and packages/ts_checker/src/relation.zig.

14 days ago

Recursive mapped aliases now match tsgo exactly

Pushed 223669022 (fix(ts-checker): diagnose recursive mapped aliases) directly to main as Chris, with no coauthors.

This ports the remaining recursiveMappedTypes behavior across three related checker paths:

  • direct and mutual mapped aliases now participate in circular dependency traversal through mapped constraints/remaps/values, keyof, and indexed access, producing the expected 3x TS2456 and 3x TS2313 diagnostics
  • concrete non-progressing mapped instantiations such as Circular<tup> now produce TS2589 at the use site, while progressive recursion such as Transform<T[P]>, DeepMap<T[K], R>, and Remap1<T[P]> remains accepted
  • recursive required-key projections such as Child<ListWidget> now produce source-anchored TS2502 and instantiated TS2615 prose, including the quoted "each" symbol and substituted ListWidget mapped body
  • the misleading declaration-emit TS4033 private-name diagnostic is suppressed for that structurally recursive member
  • added a focused regression pinning all nine diagnostics, exact TS2502/TS2615 messages, and TS4033 absence

Parity movement:

  • recursiveMappedTypes: 0/1 -> 1/1 exact
  • first 500: 500/500 retained
  • second 500: 463/500 -> 464/500
  • first 1,000: 963/1,000 -> 964/1,000
  • implementation delta: +344/-23 in packages/ts_checker/src/check.zig

Verification:

  • focused checker regression: 2/2 passed
  • exact upstream fixture: 1/1 passed
  • exact START=0 LIMIT=1000: 964/1000 passed

The all-checker binary was also attempted and independently reproduced two unrelated existing failures: the JSX contextual-literal prose assertion and the TypeBox object-static interner panic. Neither path is touched by this mapped recursion batch.

14 days ago

Full checker gate restored before the next parity batch

Pushed 66bab7f85 (fix(ts-checker): restore checker regression gate) directly to main as Chris, with no coauthors.

The complete checker run after the recursive mapped fixture exposed three deterministic defects, all now repaired:

  • JSX diagnostic literal preservation is primitive-family aware: "Hi" widens to string against numeric literal 2, while "f" remains literal against "A" | "B"
  • anonymous object diagnostic rendering validates StringIds with getOptional, so stale/foreign synthetic member ids fall back instead of panicking during TypeBox substitution
  • scalar literals are preserved only for purely covariant contextual callback returns; accumulator callbacks where U appears in both input and output now widen 0 to number, fixing higher-order reduce inference

Gate movement:

  • full ts_checker: abort plus assertion failures -> 3,340/3,340 passed
  • exact first 1,000 fixtures: 964/1,000 retained
  • implementation delta: +53/-13 in packages/ts_checker/src/check.zig

Focused verification passed for JSX literal display, TypeBox object-static substitution, higher-order reduce inference, and the existing covariant intra-expression inference case. This gives the remaining 36 early exact fixtures a clean unit-test baseline.

14 days ago

Published the Object/index parity batch to main in three Chris-only conventional commits:

  • bbdf55fa7 fix(ts-checker): align Object and index relations
    • registers apparent uppercase Object targets in the relation engine
    • accepts inherited non-nullish primitive/enum/signature/object relations while preserving explicit member conflicts
    • aligns any string/number index behavior and requires actual numeric members for named-property number-index fallback
    • delta: +124/-2
  • 8fd8e6533 fix(ts-checker): resolve Object and indexed union parity
    • lowers uppercase Object through the prototype-backed apparent instance and preserves it through generic substitution
    • makes TS2696 primary for incompatible Object assignments
    • resolves union properties through explicit properties or applicable constituent indexes, including readonly and Array prototype behavior
    • refreshes generic interface bodies onto stable type-parameter IDs
    • improves intersection/generic-alias missing-property diagnostics
    • delta: +346/-160
  • 1bcc80aa0 fix(ts-conformance): preserve lib diagnostic ownership
    • generalizes no-position lib.es5.d.ts baseline header synthesis
    • keeps fixture ownership when the first baseline diagnostic belongs to a library
    • delta: +38/-13

Exact fixtures flipped in this batch:

  • unionTypeWithIndexSignature
  • objectTypeWithStringIndexerHidingObjectIndexer
  • objectTypeHidingMembersOfObjectAssignmentCompat
  • objectTypeHidingMembersOfObjectAssignmentCompat2
  • objectTypeHidingMembersOfExtendedObject
  • objectTypeWithStringAndNumberIndexSignatureToAny

Regression evidence:

  • intended exact batch: 6/6
  • matched Object regressions: 7/7, including enum assignability, public class/interface equivalence, union subtype indexes, and {} satisfying Object
  • full ts_checker: 3345/3345
  • first 1,000 exact tsgo fixtures: 968/1000, up from 964/1000
  • focused lib header normalization test: pass
  • no coauthor trailers; all three commits authored and committed as Chris <chrisbreuer93@gmail.com>

The leading exact window now has 32 remaining failures. Next work continues from that reduced set, starting with the highest-leverage union/recursive generic clusters.

14 days ago

Published 61a71ade3 (fix(ts-checker): resolve union signature composites) to main.

What landed

  • Ported tsgo-style union signature resolution for two-constituent call and construct unions.
  • Matches compatible non-generic signatures while ignoring return types, then unions corresponding returns.
  • Combines otherwise incompatible parameter positions through intersections (number & string -> never at the call boundary).
  • Preserves optional/rest arity, abstract constructor state, source parameter names, and explicit undefined assignability.
  • Avoids structural signature side-table collisions leaking generic or explicit-this metadata into ordinary union calls.
  • Normalizes synthesized optional-parameter diagnostics to upstream prose without changing semantic acceptance.

Exact parity movement

  • unionTypeCallSignatures: failing -> exact.
  • unionTypeConstructSignatures: failing -> exact.
  • Focused union-signature group: 3/9 -> 8/9 exact.
  • First-1000 exact ratchet: 968/1000 -> 970/1000.
  • Remaining first-1000 failures: 30, with no new regression.

Verification

  • Full ts_checker suite: pass.
  • Focused call/construct + regression survey: 8 passed, 1 failed.
  • First-1000 exact survey: 970 passed, 30 failed, 0 skipped.
  • Patch size: 450 insertions, 5 deletions.

Remaining focused work

unionTypeMembers is the only failure in the nine-fixture union group. Its remaining delta is separately scoped to generic interface instantiation/inference and preserving I1<number> | I2<number> in missing-member diagnostics; the shared incompatible-call diagnostic at line 44 now matches exactly.

14 days ago

Published 9fd609004 (fix(ts-checker): preserve union member diagnostics) to main.

What changed

  • Preserve canonical named generic union annotations when reporting TS2339 for missing members on unnarrowed annotated unions.
  • Stop recovering a callable signature from one union constituent once member lookup has already emitted TS2339.
  • This matches tsgo diagnostic ownership and prevents the spurious cascading TS2345 that Home previously emitted after the missing-member diagnostic.
  • Added a focused checker regression covering MemberI1<number> | MemberI2<number> and asserting the exact TS2339 display plus absence of TS2345.

Exact parity movement

  • unionTypeMembers: failing -> exact
  • Focused union call/construct/member set: 8/9 -> 9/9
  • Exact first-1,000 corpus survey: 970/1000 -> 971/1000 (29 remaining)
  • Full ts_checker suite: passing

Patch size

  • 1 checker file
  • 64 insertions, 19 deletions

Next I am continuing through the adjacent remaining union-member/accessibility fixtures, beginning with unionTypePropertyAccessibility.

14 days ago

Published 2fc776503 (fix(ts-checker): honor union property accessibility) to main.

What changed

  • Ported tsgo createUnionOrIntersectionProperty accessibility behavior into Home union member lookup.
  • A private/protected property is now filtered out when another union constituent contributes a different declaration or only an index-signature fallback.
  • Unions whose branches inherit the exact same non-public declaration remain resolvable and produce the ordinary TS2341/TS2445 accessibility diagnostic.
  • Named union annotations used by TS2339 diagnostics now follow tsgo CompareTypes name ordering, preserving exact class/generic names without structural display-map collisions.
  • Added focused regression coverage for public unions, distinct protected/private declarations, index fallback, shared inherited declarations, and direct accessibility controls.

Exact parity movement

  • unionTypePropertyAccessibility: failing -> exact
  • Focused union signature/member/accessibility set: 9/10 -> 10/10
  • Exact first-1,000 corpus survey: 971/1000 -> 972/1000 (28 remaining)
  • Full ts_checker suite: passing

Patch size

  • 1 checker file
  • 135 insertions, 5 deletions

The leading-band union signature/member/accessibility cluster is now fully exact. I am continuing with the next logical group among the remaining 28 fixtures.

14 days ago

Published cd792ee1b (fix(ts-checker): complete unknown control-flow parity) directly to main.

Exact fixture movement

  • first 1,000 exact corpus: 972/1000 -> 975/1000
  • residual failures: 28 -> 25
  • newly exact: unknownType1, unknownType2, unknownControlFlow

Ported tsgo behavior

  • aligned unknown target-union coverage with tsgo's strict null-check isUnknownLikeUnionType shape
  • rejected number-index-only sources for strict string-index targets
  • added annotation-aware unknown diagnostics for property/index/call/new/arithmetic/comparison/unary operations without turning synthesized or unresolved internal unknown types into false positives
  • ported unknown equality narrowing, false && equality-chain joins, switch discriminant/fallthrough narrowing, and stable literal-union diagnostic display
  • preserved contextual conditional-arrow literal unions and callable contextual parameters
  • completed generic keyof intersection substitution, indexed-access TS2536 behavior, generic no-overlap comparisons, nullish/empty-object reduction, and React 18 fragment semantics
  • snapshot recursive intersection/union member slices before interning to prevent pool-growth invalidation during recursive constraint reduction

Regression coverage

  • focused exact batch: 8/8
  • historical regression sweep: 82/82
  • checker suite: 3351/3351
  • broad first-1,000 exact survey completed after the focused/full checker gates

Change size

  • packages/ts_checker/src/check.zig: +548/-53
  • packages/ts_checker/src/relation.zig: +53/-0
  • total: 601 insertions, 53 deletions

Canonical reference remains tsgo main at submodule commit b8276f35cd288aa163fad0516b60ddaacec87ee7, chiefly internal/checker/relater.go and internal/checker/flow.go for this batch.

14 days ago

Published eaac52bb1 (fix(ts-checker): complete recursive type reference parity) directly to main as Chris, with no coauthor trailers.

Exact parity movement

  • First-1000 exact fixtures: 975 -> 978
  • Residual failures: 25 -> 22
  • Newly exact: objectTypesIdentityWithPrivates3, recursiveTypeReferences1, recursiveTypeReferences2
  • Preserved/repaired exactness: namedTupleMembers, its error companion, and optionalTupleElements1

Ported behavior

  • Recursive structural aliases now use constrained placeholders while conditional argument recursion keeps a lazy seed.
  • Recursive tuple-union selection and syntax-level coinductive assignment match tsgo, including label-insensitive tuple compatibility.
  • Nested recursive-array inference preserves candidate priority and reports canonical alias/array forms.
  • Private generic overlap is based on private-member type-parameter use.
  • JSDoc typedef parsing now handles readonly tuples, top-level unions/intersections, generic aliases, sibling typedef visibility, and recursive cycle suppression.
  • Synthetic array methods register generic result parameters and apply explicit reduce<U> arguments.

Verification

  • Focused exact gate: 6/6
  • Checker suite: 3357/3357
  • Fresh-cache first-1000 survey: 978/1000, 22 failures
  • Patch size: packages/ts_checker/src/check.zig +1006/-38, including six focused regression tests

Canonical reference remains tsgo main at b8276f35cd288aa163fad0516b60ddaacec87ee7. The next pass will continue from the remaining 22 first-1000 fixtures, beginning with the adjacent generic type-alias cluster.

14 days ago

Published 08ad84b25 (fix(ts-checker): match recursive generic alias identity) directly to main as Chris, with no coauthor trailers.

Exact parity movement

  • genericTypeAliases is now exact
  • First-1000 exact fixtures: 978 -> 979
  • Residual failures: 22 -> 21

Ported behavior

  • Structurally equivalent recursive generic aliases now compare coinductively even when alias and type-parameter names differ (Foo<T> vs Bar<U>).
  • Recursive object members close on the corresponding alias pair instead of comparing unrelated placeholder constraints.
  • Explicitly instantiated generic function returns retain the same relation through local recursive aliases (Foo<A[]> vs Bar<B[]>).
  • The implementation is provenance-gated to identifiers initialized by generic calls whose functions return annotated local recursive aliases; unrelated assignments remain on the normal relation path.

Verification

  • Focused exact conformance gate: 1/1
  • Checker suite: 3358/3358
  • Patch size: packages/ts_checker/src/check.zig +413/-0
  • Added one focused regression covering direct alias assignment, alpha-renamed parameters, and generic-return flow

Canonical reference remains tsgo main at b8276f35cd288aa163fad0516b60ddaacec87ee7. Next work is the contextual union/object-literal diagnostic cluster.

14 days ago

Published e049bce10 (fix(ts-checker): preserve contextual union diagnostics) directly to main as Chris, with no coauthor trailers.

Exact parity movement

  • contextualTypeWithUnionTypeObjectLiteral is now exact
  • First-1000 exact fixtures: 979 -> 980
  • Residual failures: 21 -> 20

Ported behavior

  • Ordinary object-literal property-union mismatches are owned by the variable declaration, matching tsgo’s declaration anchor.
  • Function-valued properties retain ownership of contextual return mismatches and render a union of target signatures.
  • Declaration diagnostics preserve the complete target union, then select the closest constituent by property overlap for the nested message chain.
  • Union-valued leaves now elaborate the first incompatible constituent (string | number -> number, then string -> number).
  • Expected-property related information preserves the union receiver name (I11 | I21).

Verification

  • Focused exact conformance gate: 1/1
  • Checker suite: 3359/3359
  • Patch size: packages/ts_checker/src/check.zig +263/-3
  • Added one focused regression covering declaration-owned object mismatches and property-owned callable mismatches

Canonical reference remains tsgo main at b8276f35cd288aa163fad0516b60ddaacec87ee7.

14 days ago

Published a435c53ba (fix(ts-checker): nest Object assignment hints) directly to main as Chris, with no coauthor trailers.

Exact parity movement

  • objectTypeWithCallSignatureHidingMembersOfFunctionAssignmentCompat is now exact
  • objectTypeWithConstructSignatureHidingMembersOfFunctionAssignmentCompat is now exact
  • First-1000 exact fixtures: 980 -> 982
  • Residual failures: 20 -> 18

Ported behavior

  • Uppercase Object incompatibilities retain TS2322 as the primary assignment diagnostic.
  • TS2696 is now a nested elaboration hint instead of a standalone primary error.
  • The hint preserves the deeper callable/constructable explanation: no match for (): void or new (): any.
  • Lowercase object behavior remains unchanged.

Verification

  • Combined focused exact conformance gate: 2/2
  • Prior full checker gate: 3359/3359 before this isolated relation-only change
  • Patch size: packages/ts_checker/src/check.zig +13/-30
  • Corrected three checker assertions to validate root TS2322 plus nested TS2696

Canonical reference remains tsgo main at b8276f35cd288aa163fad0516b60ddaacec87ee7.

14 days ago

Published 08bcfe219 (fix(ts-checker): isolate bare type parameter heritage) directly to main.

This chunk completes exact tsgo parity for typeParameterAsBaseType against canonical tsgo b8276f35cd288aa163fad0516b60ddaacec87ee7:

  • bare class C<T> extends T now emits only named TS2304 (Cannot find name 'T'.) rather than also emitting TS2562/TS2507
  • compound class base expressions that reference a class type parameter still retain TS2562 and constructor validation
  • bare interface type-parameter heritage now follows the dedicated TS2312 path without the duplicate TS2430
  • corrected the uppercase Object assignment assertion after nested TS2696 hints landed in the preceding chunk

Parity movement:

  • first-1000 exact fixtures: 982 -> 983
  • first-1000 residuals: 18 -> 17
  • newly exact fixture: typeParameterAsBaseType

Verification:

  • focused exact conformance: 1/1 passed
  • corrected Object assertion: 2/2 passed
  • checker aggregate before the assertion correction: 3359 passed / 3360 total, with the sole failure being that stale assertion; the corrected assertion then passed in isolation
  • git diff --check: clean

Patch size: 24 insertions, 12 deletions across 1 file.

Commit: https://github.com/home-lang/home/commit/08bcfe2195d50a1695bdff4d375eebd737fef5f5

14 days ago

Published 84d5ec0af057c8a5a4bb0f652a3e4a161fefd612 (fix(ts-checker): flatten contextual rest tuples) directly to main as Chris, with no co-author trailers.

Parity movement

  • Flipped canonical tsgo fixture tests/cases/conformance/types/rest/restTuplesFromContextualTypes.ts to exact parity: 1/1.
  • First-1000 exact corpus: 983 -> 984 passed.
  • First-1000 residuals: 17 -> 16.
  • Baseline-aware types/rest slice remains 18/18 passed.
  • Canonical source reference: _submodules/typescript-go main at b8276f35cd288aa163fad0516b60ddaacec87ee7.

Logic ported

  • Flatten fixed tuple spreads into positional direct-IIFE callback context.
  • Treat empty tuple spreads as zero-width for arity instead of one argument.
  • Carry variadic tuple prefixes/tails through positional and rest contextual typing.
  • Resolve annotated rest tuple aliases from syntax so union branches provide per-position unions (number, string | Error) while rest bindings retain the complete tuple union.
  • Enforce an externally captured generic-rest minimum when a callback adds a required parameter beyond the target fixed prefix.
  • Preserve callee-owned/inferable generic-rest acceptance.
  • Emit the canonical nested TS2345 -> TS2328 -> TS2322 -> TS2322 required-element diagnostic chain for the failing callback.

Verification

  • Exact fixture: 1 passed, 0 failed.
  • Focused checker coverage: 3/3 cases passed (direct tuple-spread IIFE context, tuple-union annotation context, captured generic-rest rejection).
  • Baseline-aware types/rest: 18/18 passed.
  • The aggregate conformance binary still reports known unrelated always-on failures outside this fixture (typeGuardIntersectionTypes, indexersInClassType, initializerReferencingConstructorLocals, and the pre-existing types/members baseline item); the exact fixture filter itself is clean.

Patch accounting

  • packages/ts_checker/src/check.zig
  • 518 insertions, 23 deletions
  • One atomic fixture boundary; no unrelated worktree changes included.
14 days ago

Published 90cc81ca4b40020b02bbe4774d42e2bbe0730166 (fix(ts-checker): infer sliced generic rest tuples) directly to main as Chris, with no co-author trailers.

Parity movement

  • Flipped canonical tsgo fixture tests/cases/conformance/types/rest/genericRestParameters1.ts to exact parity: 1/1.
  • First-1000 exact corpus: 984 -> 985 passed.
  • First-1000 residuals: 16 -> 15.
  • Combined exact regression gate for restTuplesFromContextualTypes + genericRestParameters1: 2/2 passed.
  • Canonical source reference: _submodules/typescript-go main at b8276f35cd288aa163fad0516b60ddaacec87ee7.

Logic ported

  • Expand tuple-backed rest signatures into logical positional parameters during higher-order inference.
  • Infer the unbound suffix tuple for repeated bind calls instead of binding the entire prior rest tuple as the next scalar parameter.
  • Carry source signature minimum-argument metadata into inferred tuple member optionality, preserving zero/one/two-argument calls through optional bind chains.
  • Prevent a source-generic callback (<A, B>(a: A, b: B) => A | B) from contaminating an outer bare rest tuple; unresolved outer callback results fall back to unknown.
  • Route non-rest sources assigned to rest targets through contravariant checker signature comparison.
  • Honor the checker-level any -> never exception in that comparison and emit the canonical nested TS2322 parameter incompatibility chain.
  • Normalize whitespace after a rest ellipsis in diagnostic annotation rendering (... args -> ...args) without rewriting quoted/template text.

Verification

  • Exact genericRestParameters1: 1 passed, 0 failed.
  • Combined related exact gate: 2 passed, 0 failed.
  • Focused checker regressions: 3/3 passed (repeated required/optional bind slices plus source-generic callback, any[] rest target versus required never, rest annotation normalization).

Patch accounting

  • packages/ts_checker/src/check.zig
  • 173 insertions, 8 deletions
  • One atomic fixture boundary; concurrent home_test and untracked workspace changes were not included.
14 days ago

Accounting correction for 84d5ec0af and 90cc81ca4

A fresh, current-source measurement of both leading windows found:

  • fixtures 1-500: 500/500
  • fixtures 501-1000: 484/500
  • measured first-1000 total: 984/1000, with 16 residuals

The earlier progress comments incorrectly counted the targeted restTuplesFromContextualTypes exact flip as movement inside the leading 1,000-fixture window. That fixture is outside this window. The corrected movement is therefore:

  • 84d5ec0af (restTuplesFromContextualTypes): fixture exact 1/1, first-1000 holds at 983/1000 with 17 residuals
  • 90cc81ca4 (genericRestParameters1): fixture exact 1/1, first-1000 983 -> 984/1000, residuals 17 -> 16

The implementation, focused exact results, combined related 2/2 gate, authorship, and patch accounting in both prior comments remain correct. This comment supersedes only their first-1000 movement arithmetic.

Current measured 16-item frontier:

discriminatedUnionTypes2, keyofAndIndexedAccessErrors, keyofAndIndexedAccess, objectTypeHidingMembersOfObjectAssignmentCompat2, importWithTypeArguments, mappedTypeErrors, mappedTypeErrors2, mappedTypeRelationships, genericRestParameters3, instantiationExpressions, constraintSatisfactionWithAny, typeParameterAsTypeParameterConstraint2, instantiationExpressionErrors, varianceAnnotations, varianceAnnotationsWithCircularlyReferencesError, typeParameterConstModifiers.

I will continue using measured window totals for published movement and targeted exact filters between batched aggregate surveys.

14 days ago

TypeScript parity progress: complete rest argument-list relations

Pushed 69369fe7e (fix(ts-checker): relate complete rest argument lists) directly to main.

Fixture movement

  • genericRestParameters3: 0/1 -> 1/1 exact
  • All 13 root diagnostics now match the current tsgo oracle, with no missing or extra diagnostics.
  • Known first-1,000 window: 984/1000 -> 985/1000
  • Known residuals: 16 -> 15

This accounting follows the correction in the preceding issue update: genericRestParameters1 produced the prior 983 -> 984 movement; this commit produces 984 -> 985.

Ported semantics

  • Synthesized the complete rest argument-list type before relation instead of checking each trailing scalar against a tuple union's aggregated number index.
  • Selected tuple-union branches atomically for calls such as [string] | [number, boolean], including zero-width and wrong-width argument lists.
  • Normalized readonly tuple spreads to mutable call argument tuples without weakening ordinary readonly assignment behavior.
  • Related finite signatures through unions of accepted parameter tuples, contravariantly, so fixed signatures and tuple-rest signatures work in both assignment directions.
  • Preserved equivalence between split and nested variadic spellings (x: T, ...A and [x: T, ...A]) using lowered metadata plus normalized declaration syntax.
  • Kept unbounded array rests strict at the element level, preventing string[]/number[] false acceptance.
  • Treated custom array-derived rest containers as whole argument-list constraints, including required named members and explicit numeric tuple requirements.
  • Preserved literal tuple diagnostics, inferred never/unknown custom-rest displays, spread-array displays, and explicit generic alias displays such as CoolArray<any>.

Verification

  • zig build test -Dfilter=ts_checker: 3368/3368 passed
  • Exact tsgo conformance filter genericRestParameters3: 1/1 passed
  • Added focused regressions for tuple-union calls/assignments, custom array rests, and nested/split variadic equivalence.
  • Patch size: +884/-17 in packages/ts_checker/src/check.zig.

No unrelated runtime or untracked workspace changes were included.

14 days ago

Parity checkpoint: symbolic mapped indexes

Pushed 54a659dc3 (fix(ts-checker): relate symbolic mapped indexes) directly to main as Chris, with no coauthors.

Exact fixture movement

  • mappedTypeErrors2: now exact
  • mappedTypeRelationships: now exact
  • tracked first-1000 corpus: 985/1000 -> 987/1000
  • tracked residuals: 15 -> 13

Logic implemented

  • TypeScript-compatible type-level indexed-access diagnostics for invalid index categories, absent broad index signatures, missing literal properties, boolean key expansion, any, intersections, and prototype properties.
  • Generic keyof provenance so symbolic keys only index compatible generic objects.
  • Directional generic indexed assignments, including subtype direction, optional-source undefined, readonly mapped writes, and exact target spans.
  • Mapped-key inheritance through direct keyof T and constrained key parameters.
  • Covariant Partial<T> / Readonly<T> relations without bypassing recursive homomorphic inference.
  • Homomorphic mapped-to-mapped comparison by key coverage, indexed value bases, and optionality.
  • Exact symbolic TS2536/TS2537/TS2538/TS2339/TS2322/TS2542 message and span behavior for these paths.

Verification

  • Complete checker suite: 3,373/3,373 passed
  • Rebuilt exact conformance cluster: 2/2 passed
  • Added 5 focused regression tests
  • Patch size: +699/-18 in packages/ts_checker/src/check.zig

Remaining tracked first-1000 residuals (13)

  1. discriminatedUnionTypes2
  2. keyofAndIndexedAccessErrors
  3. keyofAndIndexedAccess
  4. objectTypeHidingMembersOfObjectAssignmentCompat2
  5. importWithTypeArguments
  6. mappedTypeErrors
  7. instantiationExpressions
  8. constraintSatisfactionWithAny
  9. typeParameterAsTypeParameterConstraint2
  10. instantiationExpressionErrors
  11. varianceAnnotations
  12. varianceAnnotationsWithCircularlyReferencesError
  13. typeParameterConstModifiers
14 days ago

Published afbeb1f68 (fix(ts-checker): enforce mapped key constraints) directly to main as Chris <chrisbreuer93@gmail.com> with no coauthors.

What moved

  • Ported direct mapped self-constraint checking, so { [P in P]: ... } now reports tsgo-compatible TS2313.
  • Enforced concrete property-key constraints for mapped types and Record, including the expected invalid Date diagnostics while preserving generic, keyof, conditional, template-literal, and string-mapping key domains.
  • Enforced concrete Pick<T, K> key constraints without prematurely rejecting unresolved generic keys.
  • Related generic indexed accesses (T[K], U[K], T[J], U[J]) according to object/key constraint direction.
  • Included inherited Object.prototype members in object indexed-access resolution and missing-key checks.
  • Guarded mapped payload reads so synthetic mapped flags cannot be decoded as mapped payloads.
  • Added 2 focused checker tests.
  • Patch size: +210 / -3 in packages/ts_checker/src/check.zig.

Validation and ratchet

  • Full checker suite: 3375/3375 passed.
  • Current tsgo main, exact first-1000 window: 974 passed / 26 failed, identical to clean HEAD and preserving the exact same 26 failure identities.
  • Targeted indexSignatures1: 1/1 exact.
  • Targeted keyofAndIndexedAccessErrors,keyofAndIndexedAccess,mappedTypeErrors substring cluster: 1/5 exact (mappedTypeErrors2 remains exact).

The initial aggregate candidate exposed one real regression, dropping 974 -> 973 by rejecting Record<${number}-${number}-${number}-${number}, string> in indexSignatures1. Differential clean/candidate runs isolated that fixture, and extending the property-key-domain classifier to template-literal and string-mapping types restored it to exact before commit.

Remaining blocker shape

The intended diagnostics are now present in mappedTypeErrors (TS2313 plus concrete mapped/Record/Pick constraints), but the fixture remains non-exact because broader mapped contextual typing, mapped member projection, declaration-conflict display, and union ordering are still incomplete. The keyofAndIndexedAccess* fixtures still need symbolic keyof algebra/display and generic indexed-access lowering beyond the now-correct direct constraint-direction relation.

14 days ago

Published f91b652ac (fix(ts-checker): resolve nonnullable indexed constraints) directly to main as Chris <chrisbreuer93@gmail.com> with no coauthors.

Exact fixture flip

unknownControlFlow is now exact. The remaining mismatch was the TypeScript #49681 shape:

type Foo = { [key: string]: unknown };
type NullableFoo = Foo | undefined;
type Bar<T extends NullableFoo> = NonNullable<T>[string];

Home already represented generic NonNullable<T> as T & {}, but indexed-access resolution followed the raw Foo | undefined constraint and lost Foo’s string index. The checker now projects a non-nullable intersection through its existing base-constraint reduction before object indexed lookup and effective string-index discovery. This preserves the generic T & {} representation for assignability/display while resolving the observable indexed type from Foo.

Movement

  • Patch: +24 / -1 in packages/ts_checker/src/check.zig.
  • Added 1 focused checker regression.
  • unknownControlFlow: 0/1 -> 1/1 exact.
  • Current tsgo main, exact first-1000 window: 974 -> 975 passed.
  • Failure identities: 26 -> 25, with unknownControlFlow removed and no replacement regression.

Verification

  • Focused unknownControlFlow: 1/1 exact.
  • Full checker suite: 3376/3376 passed.
  • Exact first-1000 survey: 975 passed / 25 failed.

I also audited objectTypeHidingMembersOfObjectAssignmentCompat2 as the apparent two-line quick win, but deliberately did not alter it: tsgo main emits TS2322 with nested TS2696 there, which Home already models and its native baseline expects, while the inherited classic TypeScript baseline expects top-level TS2696. Changing checker behavior would improve that legacy fixture by regressing the repository-owned tsgo source-of-truth lane.

14 days ago

Published 0de6ba1d1 (fix(ts-checker): validate inferred generic constraints) directly to main as Chris <chrisbreuer93@gmail.com> with no coauthors.

Exact fixture flip

constraintSatisfactionWithAny is now exact, while its constraintSatisfactionWithAny2 sibling remains exact.

The four missing diagnostics had one shared semantic cause across two resolution paths:

  1. For foo4<T extends <U>(x: U) => void>(x: T); foo4(a), Home saw the callable constraint’s locally bound U as a free outer type parameter and skipped the constraint audit. Callable constraints now keep their own generic scope while the outer T candidate is validated.
  2. Generic class constructors inferred and instantiated T but did not run the generic-argument constraint audit used by ordinary calls. Omitted-type-argument construction now validates inferred candidates against the declared class constraint.

Explicit foo<any>(...) / new C<any>(...) behavior stays accepted, matching upstream. The shared audit also checks for an existing TS2345 at the argument node before reporting, avoiding duplicate diagnostics when normal argument checking already owns the site.

Movement

  • Patch: +57 / -1 in packages/ts_checker/src/check.zig.
  • Added 1 focused regression covering 4 inferred-nullish errors and 3 explicit-any negatives.
  • constraintSatisfactionWithAny: 0/1 -> 1/1 exact.
  • Exact first-1000 window: 975 -> 976 passed.
  • Failure identities: 25 -> 24, with no replacement regression.

Verification

  • Focused constraintSatisfactionWithAny substring filter: 2/2 exact.
  • Full checker suite: 3377/3377 passed.
  • Exact first-1000 survey: 976 passed / 24 failed.
14 days ago

Published b04d85918 (fix(ts-checker): relate fixed params to source rests) directly to main as Chris <chrisbreuer93@gmail.com> with no coauthors.

Exact fixture flip

assignmentCompatWithCallSignaturesWithRestParameters is now exact.

The remaining false acceptance was:

let target: (x: number, y?: string, ...z: number[]) => number;
target = (x: number, ...z: number[]) => 1;

Home compared the shared fixed x, then both rest tails, but skipped target-only fixed parameters between those regions. That allowed a caller-provided string y to flow into the source’s number[] rest. The relater now checks every target fixed parameter beyond the source fixed prefix against the source rest element type before comparing the tails.

The companion (x: number, y?: number, ...z: number[]) target remains accepted, and arity/return logic is unchanged.

Movement

  • Patch: +22 / -1 in packages/ts_checker/src/check.zig.
  • Added 1 focused positive/negative checker regression.
  • Target fixture: 0/1 -> 1/1 exact.
  • Exact first-1000 window: 976 -> 977 passed.
  • Failure identities: 24 -> 23, with no replacement regression.

Verification

  • Focused rest-signature fixture: 1/1 exact.
  • Full checker suite: 3378/3378 passed.
  • Exact first-1000 survey: 977 passed / 23 failed.

A transient NoSpaceLeft occurred before the focused run because the project Zig cache had grown to ~14 GB. A concurrent cache cleanup removed only disposable compiler artifacts; the rebuilt focused and aggregate gates above are from the clean cache.

14 days ago

Published f9fa9915c (fix(ts-checker): narrow conditional indexed keys) directly to main as Chris, with no coauthor trailers.

This ports the conditional indexed-access proof needed by tsgo/TypeScript intersection reduction. When an indexed access T[P] occurs inside the true branch of P extends keyof T ? ... : ..., the checker now recognizes that branch-local proof and does not emit TS2538. The proof is deliberately narrow: the access must be under the true branch, the check and index must name the same bare type parameter, and the indexed object must match the keyof operand. False branches and unrelated indexed accesses retain normal diagnostics.

Patch and coverage:

  • packages/ts_checker/src/check.zig: +37/-0
  • 1 focused checker regression for the mapped merge shape

Parity movement:

  • intersectionReduction: failing -> exact
  • intersectionReductionStrict: failing -> exact
  • first-1000 exact tsgo window: 977/1000 -> 979/1000
  • failure identities: 23 -> 21, with no replacement regression

Verification:

  • focused intersection filters: 2/2 exact
  • full ts_checker: 3379/3379 passed
  • first-1000 exact tsgo survey: 979 passed, 21 failed
14 days ago

Published d40c93e8f (fix(ts-checker): refine dependent and rest calls) directly to main as Chris, with no coauthor trailers.

This closes two inherited tsgo/TypeScript fixtures with three bounded semantic changes:

  • strict empty-array arguments infer never[] when flowing directly into an unconstrained type parameter, preserving dependent constraints such as U extends { length: T }
  • when an inferred object candidate violates its substituted dependent constraint, object-literal arguments elaborate the mismatch at the offending property (TS2322) instead of collapsing to an argument-wide TS2345
  • a function whose sole parameter is ...args: [] is related as a zero-parameter source and may ignore a variadic target call, while a genuinely required (arg: never) source remains incompatible

Patch and coverage:

  • packages/ts_checker/src/check.zig: +57/-0
  • 2 focused checker regressions

Parity movement:

  • genericRestParameters1: failing -> exact
  • typeParameterAsTypeParameterConstraint2: failing -> exact
  • first-1000 exact tsgo window: 979/1000 -> 981/1000
  • failure identities: 21 -> 19, with no replacement regression

Verification:

  • focused generic/rest exact filters: 2/2 exact
  • full ts_checker: 3381/3381 passed
  • isolated first-1000 exact tsgo survey: 981 passed, 19 failed

The broad ts_conformance package still has unrelated always-on pins on current main; the native ts-conformance-test-filter isolated the authoritative exact survey above.

14 days ago

Published 28a39e7cb (fix(ts-checker): preserve filtered keyof provenance) directly to main as Chris, with no coauthor trailers.

This ports the shared tsgo/TypeScript indexed-access proof behind seven inherited fixtures. Generic mapped/conditional keys now retain their keyof provenance through:

  • direct and intersected keyof domains such as keyof T & string
  • built-in Extract<keyof T, ...> filtering
  • one-parameter selector aliases whose homomorphic mapped value can return only the mapped key or never
  • inline homomorphic selectors indexed by the same keyof base
  • conditional true branches whose extends side resolves through a keyof alias

The proof remains identity-scoped: the derived key base must match the indexed object, and arbitrary generic keys still diagnose normally.

Patch and coverage:

  • packages/ts_checker/src/check.zig: +90/-3
  • 1 focused regression covering conditional, intersection, Extract, selector-alias, and inline-selector forms

Parity movement:

  • templateLiteralTypes1: failing -> exact
  • stringMappingReduction: failing -> exact
  • templateLiteralTypes4: failing -> exact
  • conditionalTypes1: failing -> exact
  • conditionalTypes2: failing -> exact
  • recursiveMappedTypes: failing -> exact
  • mappedTypeAsClauses: failing -> exact
  • first-1000 exact tsgo window: 981/1000 -> 988/1000
  • failure identities: 19 -> 12, with no replacement regression

Verification:

  • affected exact fixtures: 7/7 exact
  • full ts_checker: 3382/3382 passed
  • isolated first-1000 exact tsgo survey: 988 passed, 12 failed

This also removes the stringMappingReduction failure from the broad always-on conformance set; unrelated ambient pins remain tracked separately.

14 days ago

Published 3c6542743 (fix(ts-parser): recover import type arguments) directly to main.

What changed

  • Routes top-level import<...> through expression-statement recovery instead of import-declaration parsing.
  • Parses bare import<T> / import<string, number> as zero-argument call-shaped recovery nodes with explicit type arguments.
  • Preserves the established import<T>(...) dynamic-import path by limiting the new recovery to type-argument lists not followed by (.
  • Excludes dynamic-import callees from instantiation-expression classification.
  • Emits TS1326 from import-call syntax before callee type resolution can return early, preserving TS1326/TS2304 ordering and avoiding duplicate late diagnostics.

Coverage and size

  • Added one parser regression and one checker regression.
  • 51 insertions, 4 deletions across ts_parser.zig and check.zig.

Exact parity movement

  • importWithTypeArguments: failing -> exact.
  • Inherited first-1000 exact window: 988/1000 -> 989/1000.
  • Residual failures: 12 -> 11, with no replacement regression.

Verification

  • TypeScript parser: 795/795.
  • TypeScript checker: 3383/3383.
  • Inherited TypeScript exact fixtures 0-999: 989/1000.

The remaining first-1000 work is now 11 fixtures; I am continuing with the next logically grouped cluster.

14 days ago

Published 866b42a59 (fix(ts-checker): filter instantiation signatures) directly to main.

What changed

  • Preserves typeof f<T> as structured instantiation-expression HIR instead of flattening the type arguments into an identifier span.
  • Emits TS1099 for empty value/type-query instantiation lists while keeping import<>(...) on its TS1326-only dynamic-import path.
  • Recognizes empty f<> recovery nodes as instantiation expressions, preventing spurious zero-argument call diagnostics.
  • Filters call and construct signatures by explicit type-argument applicability across objects and intersections.
  • Implements tsgo union behavior: when some union branches are applicable, TS2635 names the first branch that has signatures but no applicable signature; when none apply, it names the whole expression type.
  • Checks explicit constraints for every matching call/construct signature, producing the two expected TS2344 diagnostics for mixed constrained signatures.
  • Anchors TS2635 at the first type argument and preserves structural/source-annotation display provenance.

Coverage and size

  • Added one parser regression covering value, typeof, and dynamic-import empty lists.
  • Added one checker regression covering arity, object unions, partial signature unions, and call/construct constraints.
  • 163 insertions, 13 deletions across ts_parser.zig and check.zig.

Exact parity movement

  • instantiationExpressions: failing -> exact, all 16/16 diagnostics aligned.
  • Inherited first-1000 exact window: 989/1000 -> 990/1000.
  • Residual failures: 11 -> 10, with no replacement regression.

Verification

  • TypeScript parser: 796/796.
  • TypeScript checker: 3384/3384.
  • Focused inherited fixture: 1/1 exact.
  • Inherited TypeScript exact fixtures 0-999: 990/1000.

Next I am continuing with instantiationExpressionErrors, which shares the parser ambiguity machinery but has a distinct relational-expression recovery baseline.

14 days ago

Published 8d918aa (fix(ts-checker): preserve instantiated callable semantics) directly to main.\n\nThis batch ports tsgo's instantiation-expression follow-token disambiguation into the parser, including binary/logical continuation, ASI boundaries, relational ambiguity, and optional calls with explicit type arguments. HIR now preserves optional-call and explicit-type-argument semantics together, while malformed bare optional instantiations and missing assertion operands recover without losing the surrounding relational tree.\n\nThe checker now returns the filtered instantiated callable/construct type, recursively filters union/intersection/object/signature forms, removes inapplicable signatures while retaining ordinary members/indexers, and performs a pure substitution pass after the first constraint-validation pass so TS2344 is not duplicated. It also avoids call-only TS2722 diagnostics on bare instantiation expressions, reports object/boolean relational incompatibility, and preserves global-script function declarations as globalThis properties.\n\nExact parity movement:\n- instantiationExpressionErrors: flipped to all 16 expected diagnostics\n- instantiationExpressions: remains exact at all 16 expected diagnostics\n- inherited first 1,000: 990/1000 -> 991/1000\n- residual failures: 10 -> 9, with no replacement regression\n\nRegression coverage added:\n- 3 parser regressions for optional type arguments, angle-bracket ambiguity, and tsgo follow tokens\n- 1 checker regression covering expected diagnostic counts plus zero spurious TS2722/TS7017\n\nVerification:\n- parser aggregate: 799/799\n- checker aggregate: 3385/3385\n- focused inherited exact: 2/2\n- inherited first 1,000 exact: 991/1000\n\nPatch size: 387 additions, 26 removals across HIR, parser, and checker.

14 days ago

Published de5f1fb (fix(ts-checker): normalize discriminated unions) directly to main.

This ports the remaining discriminated-union behavior needed by inherited discriminatedUnionTypes2:

  • filters union variants by property truthiness/falsiness, including optional properties and named indexers
  • narrows the containing union/intersection for member === null while preserving ordinary member-only null narrowing
  • recognizes null/undefined/boolean/literal unit discriminants during object-literal excess-property target selection
  • performs bounded intersection normalization when multiple union operands share a required unit discriminator, covering ABC & (B | C)
  • preserves the full unresolved generic union in TS2339 receiver prose
  • adds a focused checker regression spanning excess properties, generic overlap, Result truthiness, generic null carriers, and intersected discriminants

Exact diagnostic movement for discriminatedUnionTypes2:

  • added the expected TS2353 on line 27 for excess property c against { a: null; b: string }
  • corrected line 32 TS2339 to report the full { a: 0; b: string } | { a: T; c: number } receiver
  • removed the extra Result.value TS2339 at line 40
  • removed the two Data | null assignment errors at lines 67 and 70
  • removed the never-member TS2339 errors at lines 114, 115, and 118

Parity movement:

  • discriminatedUnionTypes2 exact: 0/1 -> 1/1
  • inherited exact first 1,000: 991/1000 -> 992/1000
  • failures: 9 -> 8, with no replacement regression

Validation:

  • ts_checker: 3,386/3,386
  • focused inherited exact: 1/1
  • inherited exact first 1,000: 992/1000
  • diff: +241/-5 in packages/ts_checker/src/check.zig

The eight first-window residuals are now keyofAndIndexedAccessErrors, keyofAndIndexedAccess, keyofAndIndexedAccess2, objectTypeHidingMembersOfObjectAssignmentCompat2, mappedTypeErrors, varianceAnnotations, varianceAnnotationsWithCircularlyReferencesError, and typeParameterConstModifiers.

14 days ago

Published 4312577d7 (fix(ts-parser): recover variance modifier lists) to main.

This parser parity chunk:

  • consumes complete type-parameter modifier prefixes instead of bailing after the first contextual modifier;
  • reports duplicate in / out modifiers as TS1030;
  • reports reordered out in as TS1029;
  • reports in / out used as class member modifiers as TS1274;
  • adds a focused parser regression for three malformed modifier runs.

Exact movement against tsgo/TypeScript varianceAnnotations:

  • before: parsing stopped at TS1139 and hid nearly the entire expected baseline;
  • after: Home emits 27 of the 31 expected diagnostics;
  • remaining primary-fixture delta is now purely checker-side: TS2636 for circular Foo2, one direction of merged Baz, nested invariant StateNode in the ActionObject call, plus one false TS2322 for polymorphic this in a named class expression.

The separate varianceAnnotationsWithCircularlyReferencesError malformed-name fixture still intentionally remains at TS1139 and will be handled as a dedicated recovery chunk.

Movement: +37/-6 lines. Verification: ts_parser aggregate passes (800 tests); focused exact variance survey completes with the primary fixture at 27/31 expected diagnostics.

14 days ago

Published 1fa8d9b01 (fix(ts-checker): close variance annotation semantics) to main.

This closes the checker side of varianceAnnotations:

  • merged interface declarations now combine variance annotations (out T + in T => invariant), so both Baz assignment directions fail;
  • annotated aliases are revalidated after a bounded forward-alias body refresh, and variance traversal keys visits by type plus polarity, exposing the circular contravariant use in Foo2;
  • call-argument relations descend through callback/object structure to enforce explicit in out generic parameters such as StateNode<TEvent>;
  • explicit single-type-argument wrapper diagnostics retain the source type argument text, producing the exact ActionObject<PLAY | RESET> TS2345 header;
  • polymorphic this is recognized as carrying its class object shape, removing the false TS2322 in the named generic class expression.

Exact movement:

  • varianceAnnotations: 0/1 -> 1/1, now 31/31 expected diagnostics;
  • inherited first 1000: 992/1000 -> 993/1000;
  • failures: 8 -> 7.

Verification:

  • ts_checker: 3390/3390;
  • focused varianceAnnotations exact pair: 1/2, with only the malformed varianceAnnotationsWithCircularlyReferencesError parser fixture remaining;
  • uncached first-1000 exact survey: 993/1000.

Movement: +291/-8 lines. The remaining first-1000 failures are the three keyofAndIndexedAccess* fixtures, classic-only objectTypeHidingMembersOfObjectAssignmentCompat2, mappedTypeErrors, varianceAnnotationsWithCircularlyReferencesError, and typeParameterConstModifiers.

14 days ago

Published 91cd16eda (fix(ts-parser): recover malformed variance names) to main.

This closes the malformed variance-annotation fixture varianceAnnotationsWithCircularlyReferencesError by matching TypeScript's recovery and checker behavior rather than treating the repeated keywords as an unrecoverable type-parameter list:

  • recover <in in> as two missing-name type parameters, retaining both variance annotations and the reserved-word TS1359
  • recover <out out> as variance out plus contextual parameter name out
  • render empty duplicate identifiers as (Missing) for exact TS2300 prose
  • emit TS2456 for a direct generic self-alias body and suppress the redundant TS2314 on that same node
  • add focused parser and checker regressions for node counts and diagnostic counts

Exact movement:

  • variance-focused inherited fixtures: 1/2 -> 2/2
  • first 1000 inherited fixtures: 993/1000 -> 994/1000
  • failures: 7 -> 6
  • source movement: +104/-4 across parser and checker

Verification:

  • parser aggregate: pass
  • ts_checker: 3391/3391
  • focused exact variance survey: 2/2
  • fresh-cache first-1000 exact survey: 994/1000

The six remaining first-window mismatches are now keyofAndIndexedAccessErrors, keyofAndIndexedAccess, keyofAndIndexedAccess2, objectTypeHidingMembersOfObjectAssignmentCompat2, mappedTypeErrors, and typeParameterConstModifiers. The inherited Object fixture remains intentionally distinct from tsgo-native behavior: classic expects top-level TS2696, while tsgo-native expects TS2322 with nested TS2696.

14 days ago

Published 733b600f9 (fix(ts-checker): preserve const generic tuple inference) directly to main as Chris, with no coauthor.

This chunk flips inherited typeParameterConstModifiers to exact parity. The checker now:

  • interns const array literals through the canonical tuple path so readonly tuple origin survives inference;
  • collects distinct const candidates across repeated object members before contextual substitution freezes the first candidate;
  • recursively checks nested literal arrays against contextual tuple targets;
  • performs fixed-arity tuple conditional relations and captures variadic infer Rest tails as tuples;
  • tracks infer binder TypeIds so recursive substitution does not replace nested variadic binders with an outer concrete tail;
  • preserves substitutions only for reducing two-parameter tuple conditionals such as GetPath<T[A], Rest>, while retaining the prior symbolic deferral behavior for unrelated recursive aliases.

Measured movement:

  • first 1,000 inherited exact fixtures: 994/1000 -> 995/1000; failures 6 -> 5;
  • focused exact group (typeParameterConstModifiers, templateLiteralTypes3): 5/5;
  • checker aggregate: 3393/3393;
  • typeParameterConstModifiers: only the two intended TS1277 diagnostics remain.

The implementation is +151/-40 lines and adds two focused checker regressions covering repeated nested const candidates and recursive const tuple paths. The five first-1,000 residual groups are now keyofAndIndexedAccessErrors, keyofAndIndexedAccess, keyofAndIndexedAccess2, objectTypeHidingMembersOfObjectAssignmentCompat2, and mappedTypeErrors.

Sign in to comment on this issue.