@@ -1255,9 +1255,10 @@ export const enum CheckMode {
1255
1255
Inferential = 1 << 1, // Inferential typing
1256
1256
SkipContextSensitive = 1 << 2, // Skip context sensitive function expressions
1257
1257
SkipGenericFunctions = 1 << 3, // Skip single signature generic functions
1258
- IsForSignatureHelp = 1 << 4, // Call resolution for purposes of signature help
1259
- IsForStringLiteralArgumentCompletions = 1 << 5, // Do not infer from the argument currently being typed
1260
- RestBindingElement = 1 << 6, // Checking a type that is going to be used to determine the type of a rest binding element
1258
+ SkipAddingIntraExpressionSites = 1 << 4, // Skip adding intra expression sites in nested expressions since only the outermost one has to be added
1259
+ IsForSignatureHelp = 1 << 5, // Call resolution for purposes of signature help
1260
+ IsForStringLiteralArgumentCompletions = 1 << 6, // Do not infer from the argument currently being typed
1261
+ RestBindingElement = 1 << 7, // Checking a type that is going to be used to determine the type of a rest binding element
1261
1262
// e.g. in `const { a, ...rest } = foo`, when checking the type of `foo` to determine the type of `rest`,
1262
1263
// we need to preserve generic types instead of substituting them for constraints
1263
1264
}
@@ -29980,10 +29981,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
29980
29981
elementFlags.push(ElementFlags.Optional);
29981
29982
}
29982
29983
else {
29983
- const type = checkExpressionForMutableLocation(e, checkMode, forceTuple);
29984
+ const shouldAddAsIntraExpressionInferenceSite = inTupleContext && checkMode && checkMode & CheckMode.Inferential && !(checkMode & (CheckMode.SkipContextSensitive | CheckMode.SkipAddingIntraExpressionSites)) && isContextSensitive(e);
29985
+ const elementCheckMode = (checkMode || CheckMode.Normal) | (shouldAddAsIntraExpressionInferenceSite ? CheckMode.SkipAddingIntraExpressionSites : 0);
29986
+
29987
+ const type = checkExpressionForMutableLocation(e, elementCheckMode, forceTuple);
29984
29988
elementTypes.push(addOptionality(type, /*isProperty*/ true, hasOmittedExpression));
29985
29989
elementFlags.push(hasOmittedExpression ? ElementFlags.Optional : ElementFlags.Required);
29986
- if (inTupleContext && checkMode && checkMode & CheckMode.Inferential && !(checkMode & CheckMode.SkipContextSensitive) && isContextSensitive(e) ) {
29990
+ if (shouldAddAsIntraExpressionInferenceSite ) {
29987
29991
const inferenceContext = getInferenceContext(node);
29988
29992
Debug.assert(inferenceContext); // In CheckMode.Inferential we should always have an inference context
29989
29993
addIntraExpressionInferenceSite(inferenceContext, e, type);
@@ -30106,7 +30110,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
30106
30110
return links.immediateTarget;
30107
30111
}
30108
30112
30109
- function checkObjectLiteral(node: ObjectLiteralExpression, checkMode?: CheckMode): Type {
30113
+ function checkObjectLiteral(node: ObjectLiteralExpression, checkMode = CheckMode.Normal ): Type {
30110
30114
const inDestructuringPattern = isAssignmentTarget(node);
30111
30115
// Grammar checking
30112
30116
checkGrammarObjectLiteralExpression(node, inDestructuringPattern);
@@ -30148,12 +30152,17 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
30148
30152
if (memberDecl.kind === SyntaxKind.PropertyAssignment ||
30149
30153
memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment ||
30150
30154
isObjectLiteralMethod(memberDecl)) {
30151
- let type = memberDecl.kind === SyntaxKind.PropertyAssignment ? checkPropertyAssignment(memberDecl, checkMode) :
30155
+
30156
+ const shouldAddAsIntraExpressionInferenceSite = contextualType && checkMode & CheckMode.Inferential && !(checkMode & (CheckMode.SkipContextSensitive | CheckMode.SkipAddingIntraExpressionSites)) &&
30157
+ (memberDecl.kind === SyntaxKind.PropertyAssignment || memberDecl.kind === SyntaxKind.MethodDeclaration) && isContextSensitive(memberDecl);
30158
+ const propCheckMode = checkMode | (shouldAddAsIntraExpressionInferenceSite ? CheckMode.SkipAddingIntraExpressionSites : 0);
30159
+
30160
+ let type = memberDecl.kind === SyntaxKind.PropertyAssignment ? checkPropertyAssignment(memberDecl, propCheckMode) :
30152
30161
// avoid resolving the left side of the ShorthandPropertyAssignment outside of the destructuring
30153
30162
// for error recovery purposes. For example, if a user wrote `{ a = 100 }` instead of `{ a: 100 }`.
30154
30163
// we don't want to say "could not find 'a'".
30155
- memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment ? checkExpressionForMutableLocation(!inDestructuringPattern && memberDecl.objectAssignmentInitializer ? memberDecl.objectAssignmentInitializer : memberDecl.name, checkMode ) :
30156
- checkObjectLiteralMethod(memberDecl, checkMode );
30164
+ memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment ? checkExpressionForMutableLocation(!inDestructuringPattern && memberDecl.objectAssignmentInitializer ? memberDecl.objectAssignmentInitializer : memberDecl.name, propCheckMode ) :
30165
+ checkObjectLiteralMethod(memberDecl, propCheckMode );
30157
30166
if (isInJavascript) {
30158
30167
const jsDocType = getTypeForDeclarationFromJSDocComment(memberDecl);
30159
30168
if (jsDocType) {
@@ -30208,8 +30217,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
30208
30217
member = prop;
30209
30218
allPropertiesTable?.set(prop.escapedName, prop);
30210
30219
30211
- if (contextualType && checkMode && checkMode & CheckMode.Inferential && !(checkMode & CheckMode.SkipContextSensitive) &&
30212
- (memberDecl.kind === SyntaxKind.PropertyAssignment || memberDecl.kind === SyntaxKind.MethodDeclaration) && isContextSensitive(memberDecl)) {
30220
+ if (shouldAddAsIntraExpressionInferenceSite) {
30213
30221
const inferenceContext = getInferenceContext(node);
30214
30222
Debug.assert(inferenceContext); // In CheckMode.Inferential we should always have an inference context
30215
30223
const inferenceNode = memberDecl.kind === SyntaxKind.PropertyAssignment ? memberDecl.initializer : memberDecl;
@@ -30428,7 +30436,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
30428
30436
* @remarks Because this function calls getSpreadType, it needs to use the same checks as checkObjectLiteral,
30429
30437
* which also calls getSpreadType.
30430
30438
*/
30431
- function createJsxAttributesTypeFromAttributesProperty(openingLikeElement: JsxOpeningLikeElement, checkMode: CheckMode | undefined ) {
30439
+ function createJsxAttributesTypeFromAttributesProperty(openingLikeElement: JsxOpeningLikeElement, checkMode = CheckMode.Normal ) {
30432
30440
const attributes = openingLikeElement.attributes;
30433
30441
const contextualType = getContextualType(attributes, ContextFlags.None);
30434
30442
const allAttributesTable = strictNullChecks ? createSymbolTable() : undefined;
@@ -30443,7 +30451,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
30443
30451
for (const attributeDecl of attributes.properties) {
30444
30452
const member = attributeDecl.symbol;
30445
30453
if (isJsxAttribute(attributeDecl)) {
30446
- const exprType = checkJsxAttribute(attributeDecl, checkMode);
30454
+ const shouldAddAsIntraExpressionInferenceSite = contextualType && checkMode & CheckMode.Inferential && !(checkMode & (CheckMode.SkipContextSensitive | CheckMode.SkipAddingIntraExpressionSites)) && isContextSensitive(attributeDecl);
30455
+ const attributeCheckMode = checkMode | (shouldAddAsIntraExpressionInferenceSite ? CheckMode.SkipAddingIntraExpressionSites : 0);
30456
+
30457
+ const exprType = checkJsxAttribute(attributeDecl, attributeCheckMode);
30447
30458
objectFlags |= getObjectFlags(exprType) & ObjectFlags.PropagatingFlags;
30448
30459
30449
30460
const attributeSymbol = createSymbol(SymbolFlags.Property | member.flags, member.escapedName);
@@ -30465,7 +30476,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
30465
30476
addDeprecatedSuggestion(attributeDecl.name, prop.declarations, attributeDecl.name.escapedText as string);
30466
30477
}
30467
30478
}
30468
- if (contextualType && checkMode && checkMode & CheckMode.Inferential && !(checkMode & CheckMode.SkipContextSensitive) && isContextSensitive(attributeDecl) ) {
30479
+ if (shouldAddAsIntraExpressionInferenceSite ) {
30469
30480
const inferenceContext = getInferenceContext(attributes);
30470
30481
Debug.assert(inferenceContext); // In CheckMode.Inferential we should always have an inference context
30471
30482
const inferenceNode = (attributeDecl.initializer as JsxExpression).expression!;
0 commit comments