Restore idempotency to resolveObjectTypeMembers - #64372
Anders Hejlsberg (ahejlsberg) wants to merge 9 commits into
Conversation
|
TypeScript Bot (@typescript-bot) test it |
|
Starting jobs; this comment will be updated as builds start and complete.
|
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Renumbering FromTypeNode breaks the exported ObjectFlags contract and generated enum synchronization.
Get a fresh assessment by requesting another Copilot review.
Review effort: Balanced
Findings: 1
What changed in this PR
Restores idempotent object-member resolution and prevents partially resolved members from causing ghost diagnostics.
Changes:
- Delays publishing structured members until resolution completes.
- Removes unresolved-member cache state.
- Adds regression coverage and updates affected baselines.
| File | Description |
|---|---|
tsc/internal/checker/checker.go |
Revises member resolution and caching. |
tsc/internal/checker/types.go |
Removes the unresolved-members flag. |
tsc/internal/fourslash/tests/noGhostErrors_test.go |
Tests recursive inference without ghost errors. |
tsc/testdata/baselines/reference/compiler/recursiveTypeInference.types |
Updates inferred recursive types. |
tsc/testdata/baselines/reference/compiler/mutuallyRecursiveInference.errors.txt |
Records new recursion-depth diagnostic. |
tsc/testdata/baselines/reference/compiler/keyofGenericExtendingClassDoubleLayer.errors.txt |
Records new recursion-depth diagnostic. |
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
| ObjectFlagsIdenticalBaseTypeExists = 1 << 28 // has a defined cachedEquivalentBaseType member | ||
| ObjectFlagsUnresolvedMembers = 1 << 29 // Member resolution in process | ||
| ObjectFlagsFromTypeNode = 1 << 30 // Originates in resolution of AST type node | ||
| ObjectFlagsFromTypeNode = 1 << 29 // Originates in resolution of AST type node |
|
I fixed the DT error (forgot to grant a perm), but note that DT doesn't check 7.0 or 7.1 quite yet. |
|
Anders Hejlsberg (@ahejlsberg) Here they are:
tscComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
Developer Information: |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
TypeScript Bot (@typescript-bot) user test this |
|
Trying tests again... |
|
Anders Hejlsberg (@ahejlsberg) Here are the results of running the user tests with tsc comparing There were infrastructure failures potentially unrelated to your change:
Otherwise... Everything looks good! |
|
Anders Hejlsberg (@ahejlsberg) Here are the results of running the top 400 repos with tsc comparing Something interesting changed - please have a look. Details
|

With this PR we restore idempotent behavior to
resolveObjectTypeMembersas was originally intended. In #20400 we allowed type arguments to base types of a class or interface to observe the partially resolved set of members of that class or interface. This ends up being a source of ghost errors as for example observed in #62180. We really shouldn't do this and I think it is perfectly acceptable to disallow base class type arguments from eagerly obtaining the resolved set of members of the class or interface being declared.Fixes #62180.