Fix contextual typing for symbol-named properties (#46558)

* Properly handle symbol-named properties in contextual types

* Update index signature in PropertyDescriptorMap

* Add regression tests
This commit is contained in:
Anders Hejlsberg
2021-11-02 14:05:41 -07:00
committed by GitHub
parent 373accf28f
commit 33fe1b6ffc
6 changed files with 232 additions and 5 deletions

View File

@@ -26122,12 +26122,12 @@ namespace ts {
return !!(getCheckFlags(symbol) & CheckFlags.Mapped && !(symbol as MappedSymbol).type && findResolutionCycleStartIndex(symbol, TypeSystemPropertyName.Type) >= 0);
}
function getTypeOfPropertyOfContextualType(type: Type, name: __String) {
function getTypeOfPropertyOfContextualType(type: Type, name: __String, nameType?: Type) {
return mapType(type, t => {
if (isGenericMappedType(t)) {
const constraint = getConstraintTypeFromMappedType(t);
const constraintOfConstraint = getBaseConstraintOfType(constraint) || constraint;
const propertyNameType = getStringLiteralType(unescapeLeadingUnderscores(name));
const propertyNameType = nameType || getStringLiteralType(unescapeLeadingUnderscores(name));
if (isTypeAssignableTo(propertyNameType, constraintOfConstraint)) {
return substituteIndexedMappedType(t, propertyNameType);
}
@@ -26143,7 +26143,7 @@ namespace ts {
return restType;
}
}
return findApplicableIndexInfo(getIndexInfosOfStructuredType(t), getStringLiteralType(unescapeLeadingUnderscores(name)))?.type;
return findApplicableIndexInfo(getIndexInfosOfStructuredType(t), nameType || getStringLiteralType(unescapeLeadingUnderscores(name)))?.type;
}
return undefined;
}, /*noReductions*/ true);
@@ -26173,7 +26173,8 @@ namespace ts {
// For a (non-symbol) computed property, there is no reason to look up the name
// in the type. It will just be "__computed", which does not appear in any
// SymbolTable.
return getTypeOfPropertyOfContextualType(type, getSymbolOfNode(element).escapedName);
const symbol = getSymbolOfNode(element);
return getTypeOfPropertyOfContextualType(type, symbol.escapedName, getSymbolLinks(symbol).nameType);
}
if (element.name) {
const nameType = getLiteralTypeFromPropertyName(element.name);

2
src/lib/es5.d.ts vendored
View File

@@ -96,7 +96,7 @@ interface PropertyDescriptor {
}
interface PropertyDescriptorMap {
[s: string]: PropertyDescriptor;
[key: PropertyKey]: PropertyDescriptor;
}
interface Object {