-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Improve indexed access type relations #26698
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6899,10 +6899,15 @@ namespace ts { | |
} | ||
|
||
function getConstraintOfIndexedAccess(type: IndexedAccessType) { | ||
const objectType = getBaseConstraintOfType(type.objectType) || type.objectType; | ||
const indexType = getBaseConstraintOfType(type.indexType) || type.indexType; | ||
const constraint = !isGenericObjectType(objectType) && !isGenericIndexType(indexType) ? getIndexedAccessType(objectType, indexType, /*accessNode*/ undefined, errorType) : undefined; | ||
return constraint && constraint !== errorType ? constraint : undefined; | ||
const objectType = getConstraintOfType(type.objectType) || type.objectType; | ||
if (objectType !== type.objectType) { | ||
const constraint = getIndexedAccessType(objectType, type.indexType, /*accessNode*/ undefined, errorType); | ||
if (constraint && constraint !== errorType) { | ||
return constraint; | ||
} | ||
} | ||
const baseConstraint = getBaseConstraintOfType(type); | ||
return baseConstraint && baseConstraint !== type ? baseConstraint : undefined; | ||
} | ||
|
||
function getDefaultConstraintOfConditionalType(type: ConditionalType) { | ||
|
@@ -7074,9 +7079,6 @@ namespace ts { | |
if (t.flags & TypeFlags.Substitution) { | ||
return getBaseConstraint((<SubstitutionType>t).substitute); | ||
} | ||
if (isGenericMappedType(t)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This makes the constraint of a generic mapped type itself, right? I guess that makes sense since indexed accesses work that way already. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Correct. I'm not sure why this code was here, but it definitely isn't right. Removing it had no effect on baselines (including RWC baselines), but it fixes the second issue I found while exploring #26409. |
||
return emptyObjectType; | ||
} | ||
return t; | ||
} | ||
} | ||
|
@@ -11642,12 +11644,13 @@ namespace ts { | |
} | ||
} | ||
else if (target.flags & TypeFlags.IndexedAccess) { | ||
// A type S is related to a type T[K] if S is related to C, where C is the | ||
// constraint of T[K] | ||
const constraint = getConstraintForRelation(target); | ||
if (constraint) { | ||
if (result = isRelatedTo(source, constraint, reportErrors)) { | ||
return result; | ||
// A type S is related to a type T[K] if S is related to C, where C is the base constraint of T[K] | ||
if (relation !== identityRelation) { | ||
const constraint = getBaseConstraintOfType(target); | ||
if (constraint && constraint !== target) { | ||
if (result = isRelatedTo(source, constraint, reportErrors)) { | ||
return result; | ||
} | ||
} | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't this still result in a type we may need to get the constraint of if the constraint of
tyoe.objectType
is a generic mapped type (since an index on a mapped type is trivially bounded by the mapped type's template)? Or isgetConstraintOfType
not the variant that can do that?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the constraint of
type.objectType
is a mapped type, we do indeed fetch that here and form a new indexed access. Iftype.objectType
itself is a mapped type, thegetConstraintOfType
function does nothing, and we'll fall into the base constraint code below.