Skip to content

Commit b5f386e

Browse files
Merge pull request #25311 from Microsoft/betterAlwaysTrueFalseErrors
Even better "always true/false" errors
2 parents bf508cb + 441388c commit b5f386e

File tree

40 files changed

+753
-1486
lines changed

40 files changed

+753
-1486
lines changed

src/compiler/checker.ts

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20921,31 +20921,30 @@ namespace ts {
2092120921
}
2092220922

2092320923
function reportOperatorError() {
20924-
let err = chainDiagnosticMessages(
20925-
/*elaboration*/ undefined,
20926-
Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2,
20927-
tokenToString(operatorToken.kind),
20928-
typeToString(leftType),
20929-
typeToString(rightType)
20930-
);
20931-
err = giveBetterPrimaryError(err);
20932-
20933-
diagnostics.add(createDiagnosticForNodeFromMessageChain(
20934-
errorNode || operatorToken,
20935-
err
20936-
));
20924+
const leftStr = typeToString(leftType);
20925+
const rightStr = typeToString(rightType);
20926+
const errNode = errorNode || operatorToken;
20927+
if (!tryGiveBetterPrimaryError(errNode, leftStr, rightStr)) {
20928+
error(
20929+
errNode,
20930+
Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2,
20931+
tokenToString(operatorToken.kind),
20932+
leftStr,
20933+
rightStr,
20934+
);
20935+
}
2093720936
}
2093820937

20939-
function giveBetterPrimaryError(elaboration: DiagnosticMessageChain) {
20938+
function tryGiveBetterPrimaryError(errNode: Node, leftStr: string, rightStr: string) {
2094020939
switch (operatorToken.kind) {
2094120940
case SyntaxKind.EqualsEqualsEqualsToken:
2094220941
case SyntaxKind.EqualsEqualsToken:
20943-
return chainDiagnosticMessages(elaboration, Diagnostics.The_types_of_these_values_indicate_that_this_condition_will_always_be_0, "false");
20942+
return error(errNode, Diagnostics.This_condition_will_always_return_0_since_the_types_1_and_2_have_no_overlap, "false", leftStr, rightStr);
2094420943
case SyntaxKind.ExclamationEqualsEqualsToken:
2094520944
case SyntaxKind.ExclamationEqualsToken:
20946-
return chainDiagnosticMessages(elaboration, Diagnostics.The_types_of_these_values_indicate_that_this_condition_will_always_be_0, "true");
20945+
return error(errNode, Diagnostics.This_condition_will_always_return_0_since_the_types_1_and_2_have_no_overlap, "true", leftStr, rightStr);
2094720946
}
20948-
return elaboration;
20947+
return undefined;
2094920948
}
2095020949
}
2095120950

src/compiler/diagnosticMessages.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1252,7 +1252,7 @@
12521252
"category": "Error",
12531253
"code": 2366
12541254
},
1255-
"The types of these values indicate that this condition will always be '{0}'.": {
1255+
"This condition will always return '{0}' since the types '{1}' and '{2}' have no overlap.": {
12561256
"category": "Error",
12571257
"code": 2367
12581258
},

src/testRunner/unittests/tsserverProjectSystem.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5016,7 +5016,7 @@ namespace ts.projectSystem {
50165016
);
50175017
const errorResult = <protocol.Diagnostic[]>session.executeCommand(getErrRequest).response;
50185018
assert.isTrue(errorResult.length === 1);
5019-
assert.equal(errorResult[0].code, Diagnostics.The_types_of_these_values_indicate_that_this_condition_will_always_be_0.code);
5019+
assert.equal(errorResult[0].code, Diagnostics.This_condition_will_always_return_0_since_the_types_1_and_2_have_no_overlap.code);
50205020
});
50215021

50225022
it("should report semantic errors for configured js project with '// @ts-check' and skipLibCheck=true", () => {
@@ -5043,7 +5043,7 @@ namespace ts.projectSystem {
50435043
);
50445044
const errorResult = <protocol.Diagnostic[]>session.executeCommand(getErrRequest).response;
50455045
assert.isTrue(errorResult.length === 1);
5046-
assert.equal(errorResult[0].code, Diagnostics.The_types_of_these_values_indicate_that_this_condition_will_always_be_0.code);
5046+
assert.equal(errorResult[0].code, Diagnostics.This_condition_will_always_return_0_since_the_types_1_and_2_have_no_overlap.code);
50475047
});
50485048

50495049
it("should report semantic errors for configured js project with checkJs=true and skipLibCheck=true", () => {
@@ -5072,7 +5072,7 @@ namespace ts.projectSystem {
50725072
);
50735073
const errorResult = <protocol.Diagnostic[]>session.executeCommand(getErrRequest).response;
50745074
assert.isTrue(errorResult.length === 1);
5075-
assert.equal(errorResult[0].code, Diagnostics.The_types_of_these_values_indicate_that_this_condition_will_always_be_0.code);
5075+
assert.equal(errorResult[0].code, Diagnostics.This_condition_will_always_return_0_since_the_types_1_and_2_have_no_overlap.code);
50765076
});
50775077
});
50785078

tests/baselines/reference/api/tsserverlibrary.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5153,7 +5153,7 @@ declare namespace ts {
51535153
The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access: DiagnosticMessage;
51545154
Operator_0_cannot_be_applied_to_types_1_and_2: DiagnosticMessage;
51555155
Function_lacks_ending_return_statement_and_return_type_does_not_include_undefined: DiagnosticMessage;
5156-
The_types_of_these_values_indicate_that_this_condition_will_always_be_0: DiagnosticMessage;
5156+
This_condition_will_always_return_0_since_the_types_1_and_2_have_no_overlap: DiagnosticMessage;
51575157
Type_parameter_name_cannot_be_0: DiagnosticMessage;
51585158
A_parameter_property_is_only_allowed_in_a_constructor_implementation: DiagnosticMessage;
51595159
A_rest_parameter_must_be_of_an_array_type: DiagnosticMessage;

tests/baselines/reference/capturedLetConstInLoop5.errors.txt

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
tests/cases/compiler/capturedLetConstInLoop5.ts(174,13): error TS2367: The types of these values indicate that this condition will always be 'false'.
2-
Operator '==' cannot be applied to types '0' and '1'.
3-
tests/cases/compiler/capturedLetConstInLoop5.ts(229,13): error TS2367: The types of these values indicate that this condition will always be 'false'.
4-
Operator '==' cannot be applied to types '0' and '1'.
1+
tests/cases/compiler/capturedLetConstInLoop5.ts(174,13): error TS2367: This condition will always return 'false' since the types '0' and '1' have no overlap.
2+
tests/cases/compiler/capturedLetConstInLoop5.ts(229,13): error TS2367: This condition will always return 'false' since the types '0' and '1' have no overlap.
53

64

75
==== tests/cases/compiler/capturedLetConstInLoop5.ts (2 errors) ====
@@ -180,8 +178,7 @@ tests/cases/compiler/capturedLetConstInLoop5.ts(229,13): error TS2367: The types
180178
(() => x + v);
181179
if (x == 1) {
182180
~~~~~~
183-
!!! error TS2367: The types of these values indicate that this condition will always be 'false'.
184-
!!! error TS2367: Operator '==' cannot be applied to types '0' and '1'.
181+
!!! error TS2367: This condition will always return 'false' since the types '0' and '1' have no overlap.
185182
return;
186183
}
187184
}
@@ -238,8 +235,7 @@ tests/cases/compiler/capturedLetConstInLoop5.ts(229,13): error TS2367: The types
238235
(() => x + y + v);
239236
if (x == 1) {
240237
~~~~~~
241-
!!! error TS2367: The types of these values indicate that this condition will always be 'false'.
242-
!!! error TS2367: Operator '==' cannot be applied to types '0' and '1'.
238+
!!! error TS2367: This condition will always return 'false' since the types '0' and '1' have no overlap.
243239
return;
244240
}
245241
}

tests/baselines/reference/capturedLetConstInLoop5_ES6.errors.txt

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
tests/cases/compiler/capturedLetConstInLoop5_ES6.ts(174,13): error TS2367: The types of these values indicate that this condition will always be 'false'.
2-
Operator '==' cannot be applied to types '0' and '1'.
3-
tests/cases/compiler/capturedLetConstInLoop5_ES6.ts(229,13): error TS2367: The types of these values indicate that this condition will always be 'false'.
4-
Operator '==' cannot be applied to types '0' and '1'.
1+
tests/cases/compiler/capturedLetConstInLoop5_ES6.ts(174,13): error TS2367: This condition will always return 'false' since the types '0' and '1' have no overlap.
2+
tests/cases/compiler/capturedLetConstInLoop5_ES6.ts(229,13): error TS2367: This condition will always return 'false' since the types '0' and '1' have no overlap.
53

64

75
==== tests/cases/compiler/capturedLetConstInLoop5_ES6.ts (2 errors) ====
@@ -180,8 +178,7 @@ tests/cases/compiler/capturedLetConstInLoop5_ES6.ts(229,13): error TS2367: The t
180178
(() => x + v);
181179
if (x == 1) {
182180
~~~~~~
183-
!!! error TS2367: The types of these values indicate that this condition will always be 'false'.
184-
!!! error TS2367: Operator '==' cannot be applied to types '0' and '1'.
181+
!!! error TS2367: This condition will always return 'false' since the types '0' and '1' have no overlap.
185182
return;
186183
}
187184
}
@@ -238,8 +235,7 @@ tests/cases/compiler/capturedLetConstInLoop5_ES6.ts(229,13): error TS2367: The t
238235
(() => x + y + v);
239236
if (x == 1) {
240237
~~~~~~
241-
!!! error TS2367: The types of these values indicate that this condition will always be 'false'.
242-
!!! error TS2367: Operator '==' cannot be applied to types '0' and '1'.
238+
!!! error TS2367: This condition will always return 'false' since the types '0' and '1' have no overlap.
243239
return;
244240
}
245241
}

tests/baselines/reference/capturedLetConstInLoop6.errors.txt

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
1-
tests/cases/compiler/capturedLetConstInLoop6.ts(147,9): error TS2367: The types of these values indicate that this condition will always be 'false'.
2-
Operator '==' cannot be applied to types '0' and '1'.
3-
tests/cases/compiler/capturedLetConstInLoop6.ts(150,9): error TS2367: The types of these values indicate that this condition will always be 'false'.
4-
Operator '==' cannot be applied to types '0' and '2'.
5-
tests/cases/compiler/capturedLetConstInLoop6.ts(194,9): error TS2367: The types of these values indicate that this condition will always be 'false'.
6-
Operator '==' cannot be applied to types '0' and '1'.
7-
tests/cases/compiler/capturedLetConstInLoop6.ts(197,9): error TS2367: The types of these values indicate that this condition will always be 'false'.
8-
Operator '==' cannot be applied to types '0' and '2'.
1+
tests/cases/compiler/capturedLetConstInLoop6.ts(147,9): error TS2367: This condition will always return 'false' since the types '0' and '1' have no overlap.
2+
tests/cases/compiler/capturedLetConstInLoop6.ts(150,9): error TS2367: This condition will always return 'false' since the types '0' and '2' have no overlap.
3+
tests/cases/compiler/capturedLetConstInLoop6.ts(194,9): error TS2367: This condition will always return 'false' since the types '0' and '1' have no overlap.
4+
tests/cases/compiler/capturedLetConstInLoop6.ts(197,9): error TS2367: This condition will always return 'false' since the types '0' and '2' have no overlap.
95

106

117
==== tests/cases/compiler/capturedLetConstInLoop6.ts (4 errors) ====
@@ -157,14 +153,12 @@ tests/cases/compiler/capturedLetConstInLoop6.ts(197,9): error TS2367: The types
157153
(() => x);
158154
if (x == 1) {
159155
~~~~~~
160-
!!! error TS2367: The types of these values indicate that this condition will always be 'false'.
161-
!!! error TS2367: Operator '==' cannot be applied to types '0' and '1'.
156+
!!! error TS2367: This condition will always return 'false' since the types '0' and '1' have no overlap.
162157
break;
163158
}
164159
if (x == 2) {
165160
~~~~~~
166-
!!! error TS2367: The types of these values indicate that this condition will always be 'false'.
167-
!!! error TS2367: Operator '==' cannot be applied to types '0' and '2'.
161+
!!! error TS2367: This condition will always return 'false' since the types '0' and '2' have no overlap.
168162
continue;
169163
}
170164
}
@@ -210,14 +204,12 @@ tests/cases/compiler/capturedLetConstInLoop6.ts(197,9): error TS2367: The types
210204
(() => x + y);
211205
if (x == 1) {
212206
~~~~~~
213-
!!! error TS2367: The types of these values indicate that this condition will always be 'false'.
214-
!!! error TS2367: Operator '==' cannot be applied to types '0' and '1'.
207+
!!! error TS2367: This condition will always return 'false' since the types '0' and '1' have no overlap.
215208
break;
216209
}
217210
if (x == 2) {
218211
~~~~~~
219-
!!! error TS2367: The types of these values indicate that this condition will always be 'false'.
220-
!!! error TS2367: Operator '==' cannot be applied to types '0' and '2'.
212+
!!! error TS2367: This condition will always return 'false' since the types '0' and '2' have no overlap.
221213
continue;
222214
}
223215
}

tests/baselines/reference/capturedLetConstInLoop6_ES6.errors.txt

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
1-
tests/cases/compiler/capturedLetConstInLoop6_ES6.ts(147,9): error TS2367: The types of these values indicate that this condition will always be 'false'.
2-
Operator '==' cannot be applied to types '0' and '1'.
3-
tests/cases/compiler/capturedLetConstInLoop6_ES6.ts(150,9): error TS2367: The types of these values indicate that this condition will always be 'false'.
4-
Operator '==' cannot be applied to types '0' and '2'.
5-
tests/cases/compiler/capturedLetConstInLoop6_ES6.ts(194,9): error TS2367: The types of these values indicate that this condition will always be 'false'.
6-
Operator '==' cannot be applied to types '0' and '1'.
7-
tests/cases/compiler/capturedLetConstInLoop6_ES6.ts(197,9): error TS2367: The types of these values indicate that this condition will always be 'false'.
8-
Operator '==' cannot be applied to types '0' and '2'.
1+
tests/cases/compiler/capturedLetConstInLoop6_ES6.ts(147,9): error TS2367: This condition will always return 'false' since the types '0' and '1' have no overlap.
2+
tests/cases/compiler/capturedLetConstInLoop6_ES6.ts(150,9): error TS2367: This condition will always return 'false' since the types '0' and '2' have no overlap.
3+
tests/cases/compiler/capturedLetConstInLoop6_ES6.ts(194,9): error TS2367: This condition will always return 'false' since the types '0' and '1' have no overlap.
4+
tests/cases/compiler/capturedLetConstInLoop6_ES6.ts(197,9): error TS2367: This condition will always return 'false' since the types '0' and '2' have no overlap.
95

106

117
==== tests/cases/compiler/capturedLetConstInLoop6_ES6.ts (4 errors) ====
@@ -157,14 +153,12 @@ tests/cases/compiler/capturedLetConstInLoop6_ES6.ts(197,9): error TS2367: The ty
157153
(() => x);
158154
if (x == 1) {
159155
~~~~~~
160-
!!! error TS2367: The types of these values indicate that this condition will always be 'false'.
161-
!!! error TS2367: Operator '==' cannot be applied to types '0' and '1'.
156+
!!! error TS2367: This condition will always return 'false' since the types '0' and '1' have no overlap.
162157
break;
163158
}
164159
if (x == 2) {
165160
~~~~~~
166-
!!! error TS2367: The types of these values indicate that this condition will always be 'false'.
167-
!!! error TS2367: Operator '==' cannot be applied to types '0' and '2'.
161+
!!! error TS2367: This condition will always return 'false' since the types '0' and '2' have no overlap.
168162
continue;
169163
}
170164
}
@@ -210,14 +204,12 @@ tests/cases/compiler/capturedLetConstInLoop6_ES6.ts(197,9): error TS2367: The ty
210204
(() => x + y);
211205
if (x == 1) {
212206
~~~~~~
213-
!!! error TS2367: The types of these values indicate that this condition will always be 'false'.
214-
!!! error TS2367: Operator '==' cannot be applied to types '0' and '1'.
207+
!!! error TS2367: This condition will always return 'false' since the types '0' and '1' have no overlap.
215208
break;
216209
}
217210
if (x == 2) {
218211
~~~~~~
219-
!!! error TS2367: The types of these values indicate that this condition will always be 'false'.
220-
!!! error TS2367: Operator '==' cannot be applied to types '0' and '2'.
212+
!!! error TS2367: This condition will always return 'false' since the types '0' and '2' have no overlap.
221213
continue;
222214
}
223215
}

0 commit comments

Comments
 (0)