@@ -27097,8 +27097,18 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2709727097 case SyntaxKind.NonNullExpression:
2709827098 return isMatchingReference(source, (target as NonNullExpression | ParenthesizedExpression).expression);
2709927099 case SyntaxKind.BinaryExpression:
27100- return (isAssignmentExpression(target) && isMatchingReference(source, target.left)) ||
27101- (isBinaryExpression(target) && target.operatorToken.kind === SyntaxKind.CommaToken && isMatchingReference(source, target.right));
27100+ if (isAssignmentExpression(target)) {
27101+ return isMatchingReference(source, target.left);
27102+ }
27103+ if (isBinaryExpression(target)) {
27104+ switch (target.operatorToken.kind) {
27105+ case SyntaxKind.CommaToken:
27106+ return isMatchingReference(source, target.right);
27107+ case SyntaxKind.InKeyword:
27108+ return isMatchingElementAccess(source, target.right, target.left);
27109+ }
27110+ }
27111+ return false;
2710227112 }
2710327113 switch (source.kind) {
2710427114 case SyntaxKind.MetaProperty:
@@ -27129,12 +27139,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2712927139 return targetPropertyName === sourcePropertyName && isMatchingReference((source as AccessExpression).expression, (target as AccessExpression).expression);
2713027140 }
2713127141 }
27132- if (isElementAccessExpression(source) && isElementAccessExpression(target) && isIdentifier(source.argumentExpression) && isIdentifier(target.argumentExpression)) {
27133- const symbol = getResolvedSymbol(source.argumentExpression);
27134- if (symbol === getResolvedSymbol(target.argumentExpression) && (isConstantVariable(symbol) || isParameterOrMutableLocalVariable(symbol) && !isSymbolAssigned(symbol))) {
27135- return isMatchingReference(source.expression, target.expression);
27136- }
27137- }
27142+ return isElementAccessExpression(target) && isMatchingElementAccess(source, target.expression, target.argumentExpression);
2713827143 break;
2713927144 case SyntaxKind.QualifiedName:
2714027145 return isAccessExpression(target) &&
@@ -27144,6 +27149,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2714427149 return (isBinaryExpression(source) && source.operatorToken.kind === SyntaxKind.CommaToken && isMatchingReference(source.right, target));
2714527150 }
2714627151 return false;
27152+
27153+ function isMatchingElementAccess(source: Node, targetObjNode: Node, targetPropNode: Node): boolean {
27154+ if (!isElementAccessExpression(source) || !isIdentifier(source.argumentExpression) || !isIdentifier(targetPropNode)) {
27155+ return false;
27156+ }
27157+ const symbol = getResolvedSymbol(source.argumentExpression);
27158+ return (symbol === getResolvedSymbol(targetPropNode) && (isConstantVariable(symbol) || isParameterOrMutableLocalVariable(symbol) && !isSymbolAssigned(symbol)))
27159+ && isMatchingReference(source.expression, targetObjNode);
27160+ }
2714727161 }
2714827162
2714927163 function getAccessedPropertyName(access: AccessExpression | BindingElement | ParameterDeclaration): __String | undefined {
@@ -28943,7 +28957,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2894328957 const target = getReferenceCandidate(expr.right);
2894428958 if (containsMissingType(type) && isAccessExpression(reference) && isMatchingReference(reference.expression, target)) {
2894528959 const leftType = getTypeOfExpression(expr.left);
28946- if (isTypeUsableAsPropertyName(leftType) && getAccessedPropertyName(reference) === getPropertyNameFromType(leftType)) {
28960+ if (
28961+ isTypeUsableAsPropertyName(leftType)
28962+ ? getAccessedPropertyName(reference) === getPropertyNameFromType(leftType)
28963+ : isMatchingReference(reference, expr)
28964+ ) {
2894728965 return getTypeWithFacts(type, assumeTrue ? TypeFacts.NEUndefined : TypeFacts.EQUndefined);
2894828966 }
2894928967 }
0 commit comments