@@ -9431,19 +9431,19 @@ namespace ts {
9431
9431
// construct the type Box<T[X]>. We do not further simplify the result because mapped types can be recursive
9432
9432
// and we might never terminate.
9433
9433
if (isGenericMappedType(objectType)) {
9434
- return type.simplified = substituteIndexedMappedType(objectType, type);
9434
+ return type.simplified = substituteIndexedMappedType(objectType, type.indexType );
9435
9435
}
9436
9436
if (objectType.flags & TypeFlags.TypeParameter) {
9437
9437
const constraint = getConstraintOfTypeParameter(objectType as TypeParameter);
9438
9438
if (constraint && isGenericMappedType(constraint)) {
9439
- return type.simplified = substituteIndexedMappedType(constraint, type);
9439
+ return type.simplified = substituteIndexedMappedType(constraint, type.indexType );
9440
9440
}
9441
9441
}
9442
9442
return type.simplified = type;
9443
9443
}
9444
9444
9445
- function substituteIndexedMappedType(objectType: MappedType, type: IndexedAccessType ) {
9446
- const mapper = createTypeMapper([getTypeParameterFromMappedType(objectType)], [type. indexType]);
9445
+ function substituteIndexedMappedType(objectType: MappedType, indexType: Type ) {
9446
+ const mapper = createTypeMapper([getTypeParameterFromMappedType(objectType)], [indexType]);
9447
9447
const templateMapper = combineTypeMappers(objectType.mapper, mapper);
9448
9448
return instantiateType(getTemplateTypeFromMappedType(objectType), templateMapper);
9449
9449
}
@@ -16651,8 +16651,18 @@ namespace ts {
16651
16651
}
16652
16652
}
16653
16653
16654
- function getTypeOfPropertyOfContextualType(type: Type, name: __String) {
16654
+ function getTypeOfPropertyOfContextualType(type: Type, name: __String, node?: Node ) {
16655
16655
return mapType(type, t => {
16656
+ if (isGenericMappedType(t)) {
16657
+ const contextualMapper = node ? cloneTypeMapper(getContextualMapper(node)) : identityMapper;
16658
+ const instantiatedConstraintType = instantiateType(getConstraintTypeFromMappedType(t), contextualMapper);
16659
+ const propertyNameType = getLiteralType(unescapeLeadingUnderscores(name));
16660
+ if (isTypeAssignableTo(propertyNameType, instantiatedConstraintType)) {
16661
+ return substituteIndexedMappedType(t, propertyNameType);
16662
+ }
16663
+ // Fall back to looking at the apparent type: needed for
16664
+ // tests/cases/compiler/reactDefaultPropsInferenceSuccess.tsx .
16665
+ }
16656
16666
if (t.flags & TypeFlags.StructuredType) {
16657
16667
const prop = getPropertyOfType(t, name);
16658
16668
if (prop) {
@@ -16700,7 +16710,7 @@ namespace ts {
16700
16710
// in the type. It will just be "__computed", which does not appear in any
16701
16711
// SymbolTable.
16702
16712
const symbolName = getSymbolOfNode(element).escapedName;
16703
- const propertyType = getTypeOfPropertyOfContextualType(type, symbolName);
16713
+ const propertyType = getTypeOfPropertyOfContextualType(type, symbolName, element );
16704
16714
if (propertyType) {
16705
16715
return propertyType;
16706
16716
}
@@ -16717,9 +16727,9 @@ namespace ts {
16717
16727
// the type of the property with the numeric name N in T, if one exists. Otherwise, if T has a numeric index signature,
16718
16728
// it is the type of the numeric index signature in T. Otherwise, in ES6 and higher, the contextual type is the iterated
16719
16729
// type of T.
16720
- function getContextualTypeForElementExpression(arrayContextualType: Type | undefined, index: number): Type | undefined {
16730
+ function getContextualTypeForElementExpression(arrayContextualType: Type | undefined, index: number, node?: Node ): Type | undefined {
16721
16731
return arrayContextualType && (
16722
- getTypeOfPropertyOfContextualType(arrayContextualType, "" + index as __String)
16732
+ getTypeOfPropertyOfContextualType(arrayContextualType, "" + index as __String, node )
16723
16733
|| getIndexTypeOfContextualType(arrayContextualType, IndexKind.Number)
16724
16734
|| getIteratedTypeOrElementType(arrayContextualType, /*errorNode*/ undefined, /*allowStringInput*/ false, /*allowAsyncIterables*/ false, /*checkAssignability*/ false));
16725
16735
}
@@ -16734,7 +16744,7 @@ namespace ts {
16734
16744
const attributesType = getApparentTypeOfContextualType(node.openingElement.tagName);
16735
16745
// JSX expression is in children of JSX Element, we will look for an "children" atttribute (we get the name from JSX.ElementAttributesProperty)
16736
16746
const jsxChildrenPropertyName = getJsxElementChildrenPropertyName(getJsxNamespaceAt(node));
16737
- return attributesType && !isTypeAny(attributesType) && jsxChildrenPropertyName && jsxChildrenPropertyName !== "" ? getTypeOfPropertyOfContextualType(attributesType, jsxChildrenPropertyName) : undefined;
16747
+ return attributesType && !isTypeAny(attributesType) && jsxChildrenPropertyName && jsxChildrenPropertyName !== "" ? getTypeOfPropertyOfContextualType(attributesType, jsxChildrenPropertyName, node ) : undefined;
16738
16748
}
16739
16749
16740
16750
function getContextualTypeForJsxExpression(node: JsxExpression): Type | undefined {
@@ -16755,7 +16765,7 @@ namespace ts {
16755
16765
if (!attributesType || isTypeAny(attributesType)) {
16756
16766
return undefined;
16757
16767
}
16758
- return getTypeOfPropertyOfContextualType(attributesType, attribute.name.escapedText);
16768
+ return getTypeOfPropertyOfContextualType(attributesType, attribute.name.escapedText, attribute.parent );
16759
16769
}
16760
16770
else {
16761
16771
return getContextualType(attribute.parent);
@@ -16879,7 +16889,7 @@ namespace ts {
16879
16889
case SyntaxKind.ArrayLiteralExpression: {
16880
16890
const arrayLiteral = <ArrayLiteralExpression>parent;
16881
16891
const type = getApparentTypeOfContextualType(arrayLiteral);
16882
- return getContextualTypeForElementExpression(type, indexOfNode(arrayLiteral.elements, node));
16892
+ return getContextualTypeForElementExpression(type, indexOfNode(arrayLiteral.elements, node), node );
16883
16893
}
16884
16894
case SyntaxKind.ConditionalExpression:
16885
16895
return getContextualTypeForConditionalOperand(node);
@@ -17199,7 +17209,7 @@ namespace ts {
17199
17209
}
17200
17210
}
17201
17211
else {
17202
- const elementContextualType = getContextualTypeForElementExpression(contextualType, index);
17212
+ const elementContextualType = getContextualTypeForElementExpression(contextualType, index, node );
17203
17213
const type = checkExpressionForMutableLocation(e, checkMode, elementContextualType, forceTuple);
17204
17214
elementTypes.push(type);
17205
17215
}
@@ -17669,7 +17679,7 @@ namespace ts {
17669
17679
}
17670
17680
17671
17681
const contextualType = getApparentTypeOfContextualType(openingLikeElement.attributes);
17672
- const childrenContextualType = contextualType && getTypeOfPropertyOfContextualType(contextualType, jsxChildrenPropertyName);
17682
+ const childrenContextualType = contextualType && getTypeOfPropertyOfContextualType(contextualType, jsxChildrenPropertyName, openingLikeElement.attributes );
17673
17683
// If there are children in the body of JSX element, create dummy attribute "children" with the union of children types so that it will pass the attribute checking process
17674
17684
const childrenPropSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, jsxChildrenPropertyName);
17675
17685
childrenPropSymbol.type = childrenTypes.length === 1 ?
0 commit comments