Skip to content

Commit 46c0edc

Browse files
author
Andy
authored
In getContextualTypeForBinaryOperand, only need to look for = assignment operator, not e.g. += (microsoft#20037)
* In `getContextualTypeForBinaryOperand`, only need to look for `=` assignment operator, not e.g. `+=` * isNonContextualBinaryExpression -> isContextSensitiveAssignment
1 parent 36f7f30 commit 46c0edc

1 file changed

Lines changed: 34 additions & 39 deletions

File tree

src/compiler/checker.ts

Lines changed: 34 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -13862,48 +13862,43 @@ namespace ts {
1386213862
return undefined;
1386313863
}
1386413864

13865-
function getContextualTypeForBinaryOperand(node: Expression): Type {
13865+
function getContextualTypeForBinaryOperand(node: Expression): Type | undefined {
1386613866
const binaryExpression = <BinaryExpression>node.parent;
13867-
const operator = binaryExpression.operatorToken.kind;
13868-
if (isAssignmentOperator(operator)) {
13869-
if (node === binaryExpression.right) {
13870-
// Don't do this for special property assignments to avoid circularity
13871-
switch (getSpecialPropertyAssignmentKind(binaryExpression)) {
13872-
case SpecialPropertyAssignmentKind.None:
13873-
break;
13874-
case SpecialPropertyAssignmentKind.Property:
13875-
// If `binaryExpression.left` was assigned a symbol, then this is a new declaration; otherwise it is an assignment to an existing declaration.
13876-
// See `bindStaticPropertyAssignment` in `binder.ts`.
13877-
if (!binaryExpression.left.symbol) {
13878-
break;
13879-
}
13880-
// falls through
13881-
case SpecialPropertyAssignmentKind.ExportsProperty:
13882-
case SpecialPropertyAssignmentKind.ModuleExports:
13883-
case SpecialPropertyAssignmentKind.PrototypeProperty:
13884-
case SpecialPropertyAssignmentKind.ThisProperty:
13885-
return undefined;
13886-
}
13887-
// In an assignment expression, the right operand is contextually typed by the type of the left operand.
13888-
return getTypeOfExpression(binaryExpression.left);
13889-
}
13890-
}
13891-
else if (operator === SyntaxKind.BarBarToken) {
13892-
// When an || expression has a contextual type, the operands are contextually typed by that type. When an ||
13893-
// expression has no contextual type, the right operand is contextually typed by the type of the left operand.
13894-
let type = getContextualType(binaryExpression);
13895-
if (!type && node === binaryExpression.right) {
13896-
type = getTypeOfExpression(binaryExpression.left, /*cache*/ true);
13897-
}
13898-
return type;
13867+
const { left, operatorToken, right } = binaryExpression;
13868+
switch (operatorToken.kind) {
13869+
case SyntaxKind.EqualsToken:
13870+
return node === right && isContextSensitiveAssignment(binaryExpression) ? getTypeOfExpression(left) : undefined;
13871+
case SyntaxKind.BarBarToken:
13872+
// When an || expression has a contextual type, the operands are contextually typed by that type. When an ||
13873+
// expression has no contextual type, the right operand is contextually typed by the type of the left operand.
13874+
const type = getContextualType(binaryExpression);
13875+
return !type && node === right ? getTypeOfExpression(left, /*cache*/ true) : type;
13876+
case SyntaxKind.AmpersandAmpersandToken:
13877+
case SyntaxKind.CommaToken:
13878+
return node === right ? getContextualType(binaryExpression) : undefined;
13879+
default:
13880+
return undefined;
1389913881
}
13900-
else if (operator === SyntaxKind.AmpersandAmpersandToken || operator === SyntaxKind.CommaToken) {
13901-
if (node === binaryExpression.right) {
13902-
return getContextualType(binaryExpression);
13903-
}
13882+
}
13883+
// In an assignment expression, the right operand is contextually typed by the type of the left operand.
13884+
// Don't do this for special property assignments to avoid circularity.
13885+
function isContextSensitiveAssignment(binaryExpression: BinaryExpression): boolean {
13886+
const kind = getSpecialPropertyAssignmentKind(binaryExpression);
13887+
switch (kind) {
13888+
case SpecialPropertyAssignmentKind.None:
13889+
return true;
13890+
case SpecialPropertyAssignmentKind.Property:
13891+
// If `binaryExpression.left` was assigned a symbol, then this is a new declaration; otherwise it is an assignment to an existing declaration.
13892+
// See `bindStaticPropertyAssignment` in `binder.ts`.
13893+
return !binaryExpression.left.symbol;
13894+
case SpecialPropertyAssignmentKind.ExportsProperty:
13895+
case SpecialPropertyAssignmentKind.ModuleExports:
13896+
case SpecialPropertyAssignmentKind.PrototypeProperty:
13897+
case SpecialPropertyAssignmentKind.ThisProperty:
13898+
return false;
13899+
default:
13900+
Debug.assertNever(kind);
1390413901
}
13905-
13906-
return undefined;
1390713902
}
1390813903

1390913904
function getTypeOfPropertyOfContextualType(type: Type, name: __String) {

0 commit comments

Comments
 (0)