Skip to content

Commit 7f039c9

Browse files
author
Andy Hanson
committed
Improve error message for == of two different types
1 parent 67d8263 commit 7f039c9

File tree

6 files changed

+204
-161
lines changed

6 files changed

+204
-161
lines changed

src/compiler/checker.ts

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21955,7 +21955,20 @@ namespace ts {
2195521955
const leftStr = typeToString(leftType);
2195621956
const rightStr = typeToString(rightType);
2195721957
const errNode = errorNode || operatorToken;
21958-
if (!tryGiveBetterPrimaryError(errNode, leftStr, rightStr)) {
21958+
const equalsInfo = getEqualsInfo(operatorToken.kind);
21959+
if (equalsInfo !== undefined) {
21960+
const explicitConversion = getExplicitConversion(leftType, rightType);
21961+
if (explicitConversion) {
21962+
const diag = explicitConversion.side === "left"
21963+
? Diagnostics.Types_0_and_1_have_no_overlap_Consider_explicitly_converting_the_left_side_using_2_x
21964+
: Diagnostics.Types_0_and_1_have_no_overlap_Consider_explicitly_converting_the_right_side_using_2_x;
21965+
error(errNode, diag, leftStr, rightStr, explicitConversion.conversionFunctionName);
21966+
}
21967+
else {
21968+
error(errNode, Diagnostics.This_condition_will_always_return_0_since_the_types_1_and_2_have_no_overlap, String(!equalsInfo), leftStr, rightStr);
21969+
}
21970+
}
21971+
else {
2195921972
error(
2196021973
errNode,
2196121974
Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2,
@@ -21965,20 +21978,42 @@ namespace ts {
2196521978
);
2196621979
}
2196721980
}
21981+
}
2196821982

21969-
function tryGiveBetterPrimaryError(errNode: Node, leftStr: string, rightStr: string) {
21970-
switch (operatorToken.kind) {
21971-
case SyntaxKind.EqualsEqualsEqualsToken:
21972-
case SyntaxKind.EqualsEqualsToken:
21973-
return error(errNode, Diagnostics.This_condition_will_always_return_0_since_the_types_1_and_2_have_no_overlap, "false", leftStr, rightStr);
21974-
case SyntaxKind.ExclamationEqualsEqualsToken:
21975-
case SyntaxKind.ExclamationEqualsToken:
21976-
return error(errNode, Diagnostics.This_condition_will_always_return_0_since_the_types_1_and_2_have_no_overlap, "true", leftStr, rightStr);
21977-
}
21978-
return undefined;
21983+
function getEqualsInfo(operatorToken: SyntaxKind): boolean | undefined {
21984+
switch (operatorToken) {
21985+
case SyntaxKind.EqualsEqualsEqualsToken:
21986+
case SyntaxKind.EqualsEqualsToken:
21987+
return true;
21988+
case SyntaxKind.ExclamationEqualsEqualsToken:
21989+
case SyntaxKind.ExclamationEqualsToken:
21990+
return false;
21991+
default:
21992+
return undefined;
2197921993
}
2198021994
}
2198121995

21996+
interface ExplicitConversion {
21997+
readonly side: "left" | "right";
21998+
readonly conversionFunctionName: string;
21999+
}
22000+
function getExplicitConversion(left: Type, right: Type): ExplicitConversion | undefined {
22001+
const convertToRight = getFunctionNameToConvertToType(right);
22002+
if (convertToRight) return { side: "left", conversionFunctionName: convertToRight };
22003+
const convertToLeft = getFunctionNameToConvertToType(left);
22004+
if (convertToLeft) return { side: "right", conversionFunctionName: convertToLeft };
22005+
return undefined;
22006+
}
22007+
function getFunctionNameToConvertToType(type: Type): string | undefined {
22008+
return type.flags & TypeFlags.String
22009+
? "String"
22010+
: type.flags & TypeFlags.Number
22011+
? "Number"
22012+
: type.flags & TypeFlags.Boolean
22013+
? "Boolean"
22014+
: undefined;
22015+
}
22016+
2198222017
function isYieldExpressionInClass(node: YieldExpression): boolean {
2198322018
let current: Node = node;
2198422019
let parent = node.parent;

src/compiler/diagnosticMessages.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2116,6 +2116,14 @@
21162116
"category": "Error",
21172117
"code": 2586
21182118
},
2119+
"Types '{0}' and '{1}' have no overlap. Consider explicitly converting the left side using `{2}(x)`.": {
2120+
"category": "Error",
2121+
"code": 2587
2122+
},
2123+
"Types '{0}' and '{1}' have no overlap. Consider explicitly converting the right side using `{2}(x)`.": {
2124+
"category": "Error",
2125+
"code": 2588
2126+
},
21192127
"JSX element attributes type '{0}' may not be a union type.": {
21202128
"category": "Error",
21212129
"code": 2600

0 commit comments

Comments
 (0)