Skip to content

Commit

Permalink
Fixed how type of a property of a contextual type is being computed w…
Browse files Browse the repository at this point in the history
…hen intersections with indexers are used
  • Loading branch information
Andarist committed Apr 23, 2022
1 parent 982364f commit ce4998f
Showing 1 changed file with 28 additions and 11 deletions.
39 changes: 28 additions & 11 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26789,7 +26789,27 @@ namespace ts {
}

function getTypeOfPropertyOfContextualType(type: Type, name: __String, nameType?: Type) {
return mapType(type, function propertyOfContextualTypeMapper(t): Type | undefined {
return mapType(type, (t): Type | undefined => {
if (t.flags & TypeFlags.Intersection) {
const intersection = t as IntersectionType;
let newTypes = intersection.types.map(getTypeOfConcretePropertyOfContextualType).filter((t): t is Type => !!t);
if (newTypes.length > 0) {
return getIntersectionType(newTypes);
}
newTypes = intersection.types.map(getTypeOfApplicableIndexInfoOfContextualType).filter((t): t is Type => !!t);
if (newTypes.length > 0) {
return getIntersectionType(newTypes);
}
return undefined;
}
const concretePropertyType = getTypeOfConcretePropertyOfContextualType(t);
if (concretePropertyType) {
return concretePropertyType;
}
return getTypeOfApplicableIndexInfoOfContextualType(t);
}, /*noReductions*/ true);

function getTypeOfConcretePropertyOfContextualType(t: Type) {
if (isGenericMappedType(t) && !t.declaration.nameType) {
const constraint = getConstraintTypeFromMappedType(t);
const constraintOfConstraint = getBaseConstraintOfType(constraint) || constraint;
Expand All @@ -26799,14 +26819,6 @@ namespace ts {
}
return undefined;
}
if (t.flags & TypeFlags.Intersection) {
const intersection = t as IntersectionType;
const newTypes = intersection.types.map(propertyOfContextualTypeMapper).filter((t): t is Type => !!t);
if (newTypes.length === 0) {
return undefined;
}
return getIntersectionType(newTypes);
}
if (t.flags & TypeFlags.StructuredType) {
const prop = getPropertyOfType(t, name);
if (prop) {
Expand All @@ -26818,10 +26830,15 @@ namespace ts {
return restType;
}
}
return findApplicableIndexInfo(getIndexInfosOfStructuredType(t), nameType || getStringLiteralType(unescapeLeadingUnderscores(name)))?.type;
}
return undefined;
}, /*noReductions*/ true);
}
function getTypeOfApplicableIndexInfoOfContextualType(t: Type) {
if (!(t.flags & TypeFlags.StructuredType)) {
return undefined;
}
return findApplicableIndexInfo(getIndexInfosOfStructuredType(t), nameType || getStringLiteralType(unescapeLeadingUnderscores(name)))?.type;
}
}

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

0 comments on commit ce4998f

Please sign in to comment.