fix: Incorrect type resolution with nested constructors#63670
Open
thiagobarbosa wants to merge 1 commit into
Open
fix: Incorrect type resolution with nested constructors#63670thiagobarbosa wants to merge 1 commit into
thiagobarbosa wants to merge 1 commit into
Conversation
Resolves microsoft#63559 microsoft#63559 Generated by issue-coder. Review before pushing.
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes an edge-case in class base-type resolution where extends targets that are class instance types with construct signatures were incorrectly treated as if their construct signatures always returned the class instance type, causing the “outer” instance type to repeat instead of following the constructor return type chain (as in #63559).
Changes:
- Adjusted the “fast path” in
resolveBaseTypesOfClass(src/compiler/checker.ts) to avoid reusing the declared instance type when the base constructor type is actually the class instance type. - Added a new compiler test that reproduces nested-
new()constructor-return behavior. - Added
.typesand.symbolsbaselines validating the corrected resolution at each nesting level.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/compiler/checker.ts | Skips the class fast-path when the base “constructor type” is actually the class instance type, forcing resolution via construct-signature return types. |
| tests/cases/compiler/classExtendsConstructorReturningConstructor.ts | New repro test for nested constructor-return chains in extends expressions. |
| tests/baselines/reference/classExtendsConstructorReturningConstructor.types | Baseline confirming kind resolves to "A" then "B" at the correct nesting levels. |
| tests/baselines/reference/classExtendsConstructorReturningConstructor.symbols | Baseline confirming symbol binding aligns with the intended nested constructor-return resolution. |
Author
|
@microsoft-github-policy-service agree |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #63559
Problem
When a class extends a value whose type is a class instance carrying its own new construct signature, the checker
incorrectly resolved the base type using the instance type of the extended class symbol, instead of resolving it
from the construct signature. This caused the base type to be computed as the wrong (outer) instance type instead
of the type actually returned by the constructor.
Fix
In
getBaseTypeOfClassOrInterfaceconstructor-type resolution logic (src/compiler/checker.ts), the fast path thatreuses
originalBaseType(the declared type of the base constructor's symbol) is now skipped whenbaseConstructorTypeis not itself equal tooriginalBaseType— i.e., when the base constructor type is an instancetype sharing the class symbol, rather than the constructor itself. In that case, the base type is instead resolved
from the construct signatures, as intended.
Testing
Added
tests/cases/compiler/classExtendsConstructorReturningConstructor.ts, which reproduces the issue: a classextending a value with a nested new signature returning another type with its own nested new signature. Verifies
that kind resolves to "A" and "B" correctly at each nesting level (baselines: .types and .symbols).