Skip to content

Commit a7422db

Browse files
committed
Fixed how type of a property of a contextual type is being computed when intersections with indexers are used
1 parent 2a34a2c commit a7422db

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
@@ -26811,7 +26811,27 @@ namespace ts {
2681126811
}
2681226812

2681326813
function getTypeOfPropertyOfContextualType(type: Type, name: __String, nameType?: Type) {
26814-
return mapType(type, function propertyOfContextualTypeMapper(t): Type | undefined {
26814+
return mapType(type, (t): Type | undefined => {
26815+
if (t.flags & TypeFlags.Intersection) {
26816+
const intersection = t as IntersectionType;
26817+
let newTypes = mapDefined(intersection.types, getTypeOfConcretePropertyOfContextualType);
26818+
if (newTypes.length > 0) {
26819+
return getIntersectionType(newTypes);
26820+
}
26821+
newTypes = mapDefined(intersection.types, getTypeOfApplicableIndexInfoOfContextualType);
26822+
if (newTypes.length > 0) {
26823+
return getIntersectionType(newTypes);
26824+
}
26825+
return undefined;
26826+
}
26827+
const concretePropertyType = getTypeOfConcretePropertyOfContextualType(t);
26828+
if (concretePropertyType) {
26829+
return concretePropertyType;
26830+
}
26831+
return getTypeOfApplicableIndexInfoOfContextualType(t);
26832+
}, /*noReductions*/ true);
26833+
26834+
function getTypeOfConcretePropertyOfContextualType(t: Type) {
2681526835
if (isGenericMappedType(t) && !t.declaration.nameType) {
2681626836
const constraint = getConstraintTypeFromMappedType(t);
2681726837
const constraintOfConstraint = getBaseConstraintOfType(constraint) || constraint;
@@ -26821,14 +26841,6 @@ namespace ts {
2682126841
}
2682226842
return undefined;
2682326843
}
26824-
if (t.flags & TypeFlags.Intersection) {
26825-
const intersection = t as IntersectionType;
26826-
const newTypes = intersection.types.map(propertyOfContextualTypeMapper).filter((t): t is Type => !!t);
26827-
if (newTypes.length === 0) {
26828-
return undefined;
26829-
}
26830-
return getIntersectionType(newTypes);
26831-
}
2683226844
if (t.flags & TypeFlags.StructuredType) {
2683326845
const prop = getPropertyOfType(t, name);
2683426846
if (prop) {
@@ -26840,10 +26852,15 @@ namespace ts {
2684026852
return restType;
2684126853
}
2684226854
}
26843-
return findApplicableIndexInfo(getIndexInfosOfStructuredType(t), nameType || getStringLiteralType(unescapeLeadingUnderscores(name)))?.type;
2684426855
}
2684526856
return undefined;
26846-
}, /*noReductions*/ true);
26857+
}
26858+
function getTypeOfApplicableIndexInfoOfContextualType(t: Type) {
26859+
if (!(t.flags & TypeFlags.StructuredType)) {
26860+
return undefined;
26861+
}
26862+
return findApplicableIndexInfo(getIndexInfosOfStructuredType(t), nameType || getStringLiteralType(unescapeLeadingUnderscores(name)))?.type;
26863+
}
2684726864
}
2684826865

2684926866
// 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)