@@ -1258,6 +1258,7 @@ export const enum CheckMode {
12581258 RestBindingElement = 1 << 6, // Checking a type that is going to be used to determine the type of a rest binding element
12591259 // e.g. in `const { a, ...rest } = foo`, when checking the type of `foo` to determine the type of `rest`,
12601260 // we need to preserve generic types instead of substituting them for constraints
1261+ TypeOnly = 1 << 7, // Called from getTypeOfExpression, diagnostics may be omitted
12611262}
12621263
12631264/** @internal */
@@ -36760,7 +36761,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3676036761 const rightType = getLastResult(state);
3676136762 Debug.assertIsDefined(rightType);
3676236763
36763- result = checkBinaryLikeExpressionWorker(node.left, node.operatorToken, node.right, leftType, rightType, node);
36764+ result = checkBinaryLikeExpressionWorker(node.left, node.operatorToken, node.right, leftType, rightType, state.checkMode, node);
3676436765 }
3676536766
3676636767 state.skip = false;
@@ -36831,7 +36832,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3683136832 }
3683236833
3683336834 const rightType = checkExpression(right, checkMode);
36834- return checkBinaryLikeExpressionWorker(left, operatorToken, right, leftType, rightType, errorNode);
36835+ return checkBinaryLikeExpressionWorker(left, operatorToken, right, leftType, rightType, checkMode, errorNode);
3683536836 }
3683636837
3683736838 function checkBinaryLikeExpressionWorker(
@@ -36840,6 +36841,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3684036841 right: Expression,
3684136842 leftType: Type,
3684236843 rightType: Type,
36844+ checkMode?: CheckMode,
3684336845 errorNode?: Node
3684436846 ): Type {
3684536847 const operator = operatorToken.kind;
@@ -36993,14 +36995,18 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3699336995 case SyntaxKind.ExclamationEqualsToken:
3699436996 case SyntaxKind.EqualsEqualsEqualsToken:
3699536997 case SyntaxKind.ExclamationEqualsEqualsToken:
36996- if (isLiteralExpressionOfObject(left) || isLiteralExpressionOfObject(right)) {
36997- const eqType = operator === SyntaxKind.EqualsEqualsToken || operator === SyntaxKind.EqualsEqualsEqualsToken;
36998- error(errorNode, Diagnostics.This_condition_will_always_return_0_since_JavaScript_compares_objects_by_reference_not_value, eqType ? "false" : "true");
36998+ // We suppress errors in CheckMode.TypeOnly (meaning the invocation came from getTypeOfExpression). During
36999+ // control flow analysis it is possible for operands to temporarily have narrower types, and those narrower
37000+ // types may cause the operands to not be comparable. We don't want such errors reported (see #46475).
37001+ if (!(checkMode && checkMode & CheckMode.TypeOnly)) {
37002+ if (isLiteralExpressionOfObject(left) || isLiteralExpressionOfObject(right)) {
37003+ const eqType = operator === SyntaxKind.EqualsEqualsToken || operator === SyntaxKind.EqualsEqualsEqualsToken;
37004+ error(errorNode, Diagnostics.This_condition_will_always_return_0_since_JavaScript_compares_objects_by_reference_not_value, eqType ? "false" : "true");
37005+ }
37006+ checkNaNEquality(errorNode, operator, left, right);
37007+ reportOperatorErrorUnless((left, right) => isTypeEqualityComparableTo(left, right) || isTypeEqualityComparableTo(right, left));
3699937008 }
37000- checkNaNEquality(errorNode, operator, left, right);
37001- reportOperatorErrorUnless((left, right) => isTypeEqualityComparableTo(left, right) || isTypeEqualityComparableTo(right, left));
3700237009 return booleanType;
37003-
3700437010 case SyntaxKind.InstanceOfKeyword:
3700537011 return checkInstanceOfExpression(left, right, leftType, rightType);
3700637012 case SyntaxKind.InKeyword:
@@ -37355,7 +37361,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3735537361 }
3735637362
3735737363 function checkConditionalExpression(node: ConditionalExpression, checkMode?: CheckMode): Type {
37358- const type = checkTruthinessExpression(node.condition);
37364+ const type = checkTruthinessExpression(node.condition, checkMode );
3735937365 checkTestingKnownTruthyCallableOrAwaitableType(node.condition, type, node.whenTrue);
3736037366 const type1 = checkExpression(node.whenTrue, checkMode);
3736137367 const type2 = checkExpression(node.whenFalse, checkMode);
@@ -37736,7 +37742,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3773637742 }
3773737743 }
3773837744 const startInvocationCount = flowInvocationCount;
37739- const type = checkExpression(node);
37745+ const type = checkExpression(node, CheckMode.TypeOnly );
3774037746 // If control flow analysis was required to determine the type, it is worth caching.
3774137747 if (flowInvocationCount !== startInvocationCount) {
3774237748 const cache = flowTypeCache || (flowTypeCache = []);
0 commit comments