Skip to content

Commit ce4998f

Browse files
committed
Fixed how type of a property of a contextual type is being computed when intersections with indexers are used
1 parent 982364f commit ce4998f

File tree

1 file changed

+28
-11
lines changed

1 file changed

+28
-11
lines changed

src/compiler/checker.ts

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26789,7 +26789,27 @@ namespace ts {
2678926789
}
2679026790

2679126791
function getTypeOfPropertyOfContextualType(type: Type, name: __String, nameType?: Type) {
26792-
return mapType(type, function propertyOfContextualTypeMapper(t): Type | undefined {
26792+
return mapType(type, (t): Type | undefined => {
26793+
if (t.flags & TypeFlags.Intersection) {
26794+
const intersection = t as IntersectionType;
26795+
let newTypes = intersection.types.map(getTypeOfConcretePropertyOfContextualType).filter((t): t is Type => !!t);
26796+
if (newTypes.length > 0) {
26797+
return getIntersectionType(newTypes);
26798+
}
26799+
newTypes = intersection.types.map(getTypeOfApplicableIndexInfoOfContextualType).filter((t): t is Type => !!t);
26800+
if (newTypes.length > 0) {
26801+
return getIntersectionType(newTypes);
26802+
}
26803+
return undefined;
26804+
}
26805+
const concretePropertyType = getTypeOfConcretePropertyOfContextualType(t);
26806+
if (concretePropertyType) {
26807+
return concretePropertyType;
26808+
}
26809+
return getTypeOfApplicableIndexInfoOfContextualType(t);
26810+
}, /*noReductions*/ true);
26811+
26812+
function getTypeOfConcretePropertyOfContextualType(t: Type) {
2679326813
if (isGenericMappedType(t) && !t.declaration.nameType) {
2679426814
const constraint = getConstraintTypeFromMappedType(t);
2679526815
const constraintOfConstraint = getBaseConstraintOfType(constraint) || constraint;
@@ -26799,14 +26819,6 @@ namespace ts {
2679926819
}
2680026820
return undefined;
2680126821
}
26802-
if (t.flags & TypeFlags.Intersection) {
26803-
const intersection = t as IntersectionType;
26804-
const newTypes = intersection.types.map(propertyOfContextualTypeMapper).filter((t): t is Type => !!t);
26805-
if (newTypes.length === 0) {
26806-
return undefined;
26807-
}
26808-
return getIntersectionType(newTypes);
26809-
}
2681026822
if (t.flags & TypeFlags.StructuredType) {
2681126823
const prop = getPropertyOfType(t, name);
2681226824
if (prop) {
@@ -26818,10 +26830,15 @@ namespace ts {
2681826830
return restType;
2681926831
}
2682026832
}
26821-
return findApplicableIndexInfo(getIndexInfosOfStructuredType(t), nameType || getStringLiteralType(unescapeLeadingUnderscores(name)))?.type;
2682226833
}
2682326834
return undefined;
26824-
}, /*noReductions*/ true);
26835+
}
26836+
function getTypeOfApplicableIndexInfoOfContextualType(t: Type) {
26837+
if (!(t.flags & TypeFlags.StructuredType)) {
26838+
return undefined;
26839+
}
26840+
return findApplicableIndexInfo(getIndexInfosOfStructuredType(t), nameType || getStringLiteralType(unescapeLeadingUnderscores(name)))?.type;
26841+
}
2682526842
}
2682626843

2682726844
// In an object literal contextually typed by a type T, the contextual type of a property assignment is the type of

0 commit comments

Comments
 (0)