Move eitherIsNotLiteral check into switch and === checks
This improves error messages
This commit is contained in:
parent
b0080a253d
commit
ebef408dfa
|
@ -13814,12 +13814,6 @@ namespace ts {
|
|||
}
|
||||
|
||||
function isTypeEqualityComparableTo(source: Type, target: Type) {
|
||||
const sourceIsLiteral = isLiteralType(source);
|
||||
const targetIsLiteral = isLiteralType(target);
|
||||
if (!sourceIsLiteral || !targetIsLiteral) {
|
||||
source = sourceIsLiteral ? getBaseTypeOfLiteralType(source) : source;
|
||||
target = targetIsLiteral ? getBaseTypeOfLiteralType(target) : target;
|
||||
}
|
||||
return (target.flags & TypeFlags.Nullable) !== 0 || isTypeComparableTo(source, target);
|
||||
}
|
||||
|
||||
|
@ -13960,6 +13954,12 @@ namespace ts {
|
|||
case SyntaxKind.ExclamationEqualsToken:
|
||||
case SyntaxKind.EqualsEqualsEqualsToken:
|
||||
case SyntaxKind.ExclamationEqualsEqualsToken:
|
||||
const leftIsLiteral = isLiteralType(leftType);
|
||||
const rightIsLiteral = isLiteralType(rightType);
|
||||
if (!leftIsLiteral || !rightIsLiteral) {
|
||||
leftType = leftIsLiteral ? getBaseTypeOfLiteralType(leftType) : leftType;
|
||||
rightType = rightIsLiteral ? getBaseTypeOfLiteralType(rightType) : rightType;
|
||||
}
|
||||
if (!isTypeEqualityComparableTo(leftType, rightType) && !isTypeEqualityComparableTo(rightType, leftType)) {
|
||||
reportOperatorError();
|
||||
}
|
||||
|
@ -16882,7 +16882,7 @@ namespace ts {
|
|||
let firstDefaultClause: CaseOrDefaultClause;
|
||||
let hasDuplicateDefaultClause = false;
|
||||
|
||||
const expressionType = checkExpression(node.expression);
|
||||
let expressionType = checkExpression(node.expression);
|
||||
forEach(node.caseBlock.clauses, clause => {
|
||||
// Grammar check for duplicate default clauses, skip if we already report duplicate default clause
|
||||
if (clause.kind === SyntaxKind.DefaultClause && !hasDuplicateDefaultClause) {
|
||||
|
@ -16903,7 +16903,13 @@ namespace ts {
|
|||
// TypeScript 1.0 spec (April 2014): 5.9
|
||||
// In a 'switch' statement, each 'case' expression must be of a type that is comparable
|
||||
// to or from the type of the 'switch' expression.
|
||||
const caseType = checkExpression(caseClause.expression);
|
||||
let caseType = checkExpression(caseClause.expression);
|
||||
const caseIsLiteral = isLiteralType(caseType);
|
||||
const expressionIsLiteral = isLiteralType(expressionType);
|
||||
if (!caseIsLiteral || !expressionIsLiteral) {
|
||||
caseType = caseIsLiteral ? getBaseTypeOfLiteralType(caseType) : caseType;
|
||||
expressionType = expressionIsLiteral ? getBaseTypeOfLiteralType(expressionType) : expressionType;
|
||||
}
|
||||
if (!isTypeEqualityComparableTo(expressionType, caseType)) {
|
||||
// expressionType is not comparable to caseType, try the reversed check and report errors if it fails
|
||||
checkTypeComparableTo(caseType, expressionType, caseClause.expression, /*headMessage*/ undefined);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
tests/cases/compiler/expr.ts(87,5): error TS2365: Operator '==' cannot be applied to types 'number' and 'string'.
|
||||
tests/cases/compiler/expr.ts(88,5): error TS2365: Operator '==' cannot be applied to types 'number' and 'false'.
|
||||
tests/cases/compiler/expr.ts(88,5): error TS2365: Operator '==' cannot be applied to types 'number' and 'boolean'.
|
||||
tests/cases/compiler/expr.ts(94,5): error TS2365: Operator '==' cannot be applied to types 'string' and 'number'.
|
||||
tests/cases/compiler/expr.ts(95,5): error TS2365: Operator '==' cannot be applied to types 'string' and 'false'.
|
||||
tests/cases/compiler/expr.ts(95,5): error TS2365: Operator '==' cannot be applied to types 'string' and 'boolean'.
|
||||
tests/cases/compiler/expr.ts(98,5): error TS2365: Operator '==' cannot be applied to types 'string' and 'E'.
|
||||
tests/cases/compiler/expr.ts(115,5): error TS2365: Operator '==' cannot be applied to types 'E' and 'string'.
|
||||
tests/cases/compiler/expr.ts(116,5): error TS2365: Operator '==' cannot be applied to types 'E' and 'false'.
|
||||
|
@ -161,7 +161,7 @@ tests/cases/compiler/expr.ts(242,7): error TS2363: The right-hand side of an ari
|
|||
!!! error TS2365: Operator '==' cannot be applied to types 'number' and 'string'.
|
||||
n==b;
|
||||
~~~~
|
||||
!!! error TS2365: Operator '==' cannot be applied to types 'number' and 'false'.
|
||||
!!! error TS2365: Operator '==' cannot be applied to types 'number' and 'boolean'.
|
||||
n==i;
|
||||
n==n;
|
||||
n==e;
|
||||
|
@ -172,7 +172,7 @@ tests/cases/compiler/expr.ts(242,7): error TS2363: The right-hand side of an ari
|
|||
!!! error TS2365: Operator '==' cannot be applied to types 'string' and 'number'.
|
||||
s==b;
|
||||
~~~~
|
||||
!!! error TS2365: Operator '==' cannot be applied to types 'string' and 'false'.
|
||||
!!! error TS2365: Operator '==' cannot be applied to types 'string' and 'boolean'.
|
||||
s==i;
|
||||
s==s;
|
||||
s==e;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
tests/cases/conformance/statements/for-inStatements/for-inStatementsArrayErrors.ts(5,14): error TS7015: Element implicitly has an 'any' type because index expression is not of type 'number'.
|
||||
tests/cases/conformance/statements/for-inStatements/for-inStatementsArrayErrors.ts(6,16): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type.
|
||||
tests/cases/conformance/statements/for-inStatements/for-inStatementsArrayErrors.ts(7,9): error TS2365: Operator '===' cannot be applied to types 'string' and '1'.
|
||||
tests/cases/conformance/statements/for-inStatements/for-inStatementsArrayErrors.ts(7,9): error TS2365: Operator '===' cannot be applied to types 'string' and 'number'.
|
||||
tests/cases/conformance/statements/for-inStatements/for-inStatementsArrayErrors.ts(9,16): error TS2339: Property 'unknownProperty' does not exist on type 'string'.
|
||||
tests/cases/conformance/statements/for-inStatements/for-inStatementsArrayErrors.ts(13,10): error TS2403: Subsequent variable declarations must have the same type. Variable 'i' must be of type 'number', but here has type 'string'.
|
||||
tests/cases/conformance/statements/for-inStatements/for-inStatementsArrayErrors.ts(17,10): error TS2403: Subsequent variable declarations must have the same type. Variable 'j' must be of type 'any', but here has type 'string'.
|
||||
|
@ -19,7 +19,7 @@ tests/cases/conformance/statements/for-inStatements/for-inStatementsArrayErrors.
|
|||
!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type.
|
||||
if (x === 1) {
|
||||
~~~~~~~
|
||||
!!! error TS2365: Operator '===' cannot be applied to types 'string' and '1'.
|
||||
!!! error TS2365: Operator '===' cannot be applied to types 'string' and 'number'.
|
||||
}
|
||||
let a3 = x.unknownProperty;
|
||||
~~~~~~~~~~~~~~~
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
tests/cases/conformance/types/literal/stringLiteralsAssertionsInEqualityComparisons02.ts(3,9): error TS2365: Operator '===' cannot be applied to types '"foo"' and '"baz"'.
|
||||
tests/cases/conformance/types/literal/stringLiteralsAssertionsInEqualityComparisons02.ts(5,9): error TS2365: Operator '==' cannot be applied to types '"foo"' and 'number'.
|
||||
tests/cases/conformance/types/literal/stringLiteralsAssertionsInEqualityComparisons02.ts(5,9): error TS2365: Operator '==' cannot be applied to types 'string' and 'number'.
|
||||
tests/cases/conformance/types/literal/stringLiteralsAssertionsInEqualityComparisons02.ts(5,19): error TS2352: Type 'string' cannot be converted to type 'number'.
|
||||
|
||||
|
||||
|
@ -12,7 +12,7 @@ tests/cases/conformance/types/literal/stringLiteralsAssertionsInEqualityComparis
|
|||
var b = "foo" !== ("bar" as "foo");
|
||||
var c = "foo" == (<number>"bar");
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2365: Operator '==' cannot be applied to types '"foo"' and 'number'.
|
||||
!!! error TS2365: Operator '==' cannot be applied to types 'string' and 'number'.
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS2352: Type 'string' cannot be converted to type 'number'.
|
||||
var d = "foo" === ("bar" as EnhancedString);
|
|
@ -1,4 +1,4 @@
|
|||
tests/cases/compiler/switchAssignmentCompat.ts(4,10): error TS2678: Type 'typeof Foo' is not comparable to type '0'.
|
||||
tests/cases/compiler/switchAssignmentCompat.ts(4,10): error TS2678: Type 'typeof Foo' is not comparable to type 'number'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/switchAssignmentCompat.ts (1 errors) ====
|
||||
|
@ -7,6 +7,6 @@ tests/cases/compiler/switchAssignmentCompat.ts(4,10): error TS2678: Type 'typeof
|
|||
switch (0) {
|
||||
case Foo: break; // Error expected
|
||||
~~~
|
||||
!!! error TS2678: Type 'typeof Foo' is not comparable to type '0'.
|
||||
!!! error TS2678: Type 'typeof Foo' is not comparable to type 'number'.
|
||||
}
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
tests/cases/compiler/switchCaseCircularRefeference.ts(5,10): error TS2678: Type '{ a: "A"; b: any; } | { a: "C"; e: any; }' is not comparable to type '"A" | "C"'.
|
||||
Type '{ a: "C"; e: any; }' is not comparable to type '"A" | "C"'.
|
||||
Type '{ a: "C"; e: any; }' is not comparable to type '"C"'.
|
||||
tests/cases/compiler/switchCaseCircularRefeference.ts(5,10): error TS2678: Type '{ a: "A"; b: any; } | { a: "C"; e: any; }' is not comparable to type 'string'.
|
||||
Type '{ a: "C"; e: any; }' is not comparable to type 'string'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/switchCaseCircularRefeference.ts (1 errors) ====
|
||||
|
@ -10,9 +9,8 @@ tests/cases/compiler/switchCaseCircularRefeference.ts(5,10): error TS2678: Type
|
|||
switch (x.a) {
|
||||
case x:
|
||||
~
|
||||
!!! error TS2678: Type '{ a: "A"; b: any; } | { a: "C"; e: any; }' is not comparable to type '"A" | "C"'.
|
||||
!!! error TS2678: Type '{ a: "C"; e: any; }' is not comparable to type '"A" | "C"'.
|
||||
!!! error TS2678: Type '{ a: "C"; e: any; }' is not comparable to type '"C"'.
|
||||
!!! error TS2678: Type '{ a: "A"; b: any; } | { a: "C"; e: any; }' is not comparable to type 'string'.
|
||||
!!! error TS2678: Type '{ a: "C"; e: any; }' is not comparable to type 'string'.
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -1,25 +1,22 @@
|
|||
tests/cases/compiler/switchCasesExpressionTypeMismatch.ts(4,10): error TS2678: Type 'typeof Foo' is not comparable to type '0'.
|
||||
tests/cases/compiler/switchCasesExpressionTypeMismatch.ts(5,10): error TS2678: Type '"sss"' is not comparable to type '0'.
|
||||
tests/cases/compiler/switchCasesExpressionTypeMismatch.ts(6,10): error TS2678: Type '123' is not comparable to type '0'.
|
||||
tests/cases/compiler/switchCasesExpressionTypeMismatch.ts(7,10): error TS2678: Type 'true' is not comparable to type '0'.
|
||||
tests/cases/compiler/switchCasesExpressionTypeMismatch.ts(4,10): error TS2678: Type 'typeof Foo' is not comparable to type 'number'.
|
||||
tests/cases/compiler/switchCasesExpressionTypeMismatch.ts(5,10): error TS2678: Type 'string' is not comparable to type 'number'.
|
||||
tests/cases/compiler/switchCasesExpressionTypeMismatch.ts(7,10): error TS2678: Type 'boolean' is not comparable to type 'number'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/switchCasesExpressionTypeMismatch.ts (4 errors) ====
|
||||
==== tests/cases/compiler/switchCasesExpressionTypeMismatch.ts (3 errors) ====
|
||||
class Foo { }
|
||||
|
||||
switch (0) {
|
||||
case Foo: break; // Error
|
||||
~~~
|
||||
!!! error TS2678: Type 'typeof Foo' is not comparable to type '0'.
|
||||
!!! error TS2678: Type 'typeof Foo' is not comparable to type 'number'.
|
||||
case "sss": break; // Error
|
||||
~~~~~
|
||||
!!! error TS2678: Type '"sss"' is not comparable to type '0'.
|
||||
!!! error TS2678: Type 'string' is not comparable to type 'number'.
|
||||
case 123: break; // No Error
|
||||
~~~
|
||||
!!! error TS2678: Type '123' is not comparable to type '0'.
|
||||
case true: break; // Error
|
||||
~~~~
|
||||
!!! error TS2678: Type 'true' is not comparable to type '0'.
|
||||
!!! error TS2678: Type 'boolean' is not comparable to type 'number'.
|
||||
}
|
||||
|
||||
var s: any = 0;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
tests/cases/conformance/es6/Symbols/symbolType9.ts(3,1): error TS2365: Operator '==' cannot be applied to types 'symbol' and 'true'.
|
||||
tests/cases/conformance/es6/Symbols/symbolType9.ts(5,1): error TS2365: Operator '!=' cannot be applied to types '0' and 'symbol'.
|
||||
tests/cases/conformance/es6/Symbols/symbolType9.ts(7,1): error TS2365: Operator '===' cannot be applied to types 'symbol' and '1'.
|
||||
tests/cases/conformance/es6/Symbols/symbolType9.ts(9,1): error TS2365: Operator '!==' cannot be applied to types 'false' and 'symbol'.
|
||||
tests/cases/conformance/es6/Symbols/symbolType9.ts(3,1): error TS2365: Operator '==' cannot be applied to types 'symbol' and 'boolean'.
|
||||
tests/cases/conformance/es6/Symbols/symbolType9.ts(5,1): error TS2365: Operator '!=' cannot be applied to types 'number' and 'symbol'.
|
||||
tests/cases/conformance/es6/Symbols/symbolType9.ts(7,1): error TS2365: Operator '===' cannot be applied to types 'symbol' and 'number'.
|
||||
tests/cases/conformance/es6/Symbols/symbolType9.ts(9,1): error TS2365: Operator '!==' cannot be applied to types 'boolean' and 'symbol'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/es6/Symbols/symbolType9.ts (4 errors) ====
|
||||
|
@ -9,16 +9,16 @@ tests/cases/conformance/es6/Symbols/symbolType9.ts(9,1): error TS2365: Operator
|
|||
s == s;
|
||||
s == true;
|
||||
~~~~~~~~~
|
||||
!!! error TS2365: Operator '==' cannot be applied to types 'symbol' and 'true'.
|
||||
!!! error TS2365: Operator '==' cannot be applied to types 'symbol' and 'boolean'.
|
||||
s != s;
|
||||
0 != s;
|
||||
~~~~~~
|
||||
!!! error TS2365: Operator '!=' cannot be applied to types '0' and 'symbol'.
|
||||
!!! error TS2365: Operator '!=' cannot be applied to types 'number' and 'symbol'.
|
||||
s === s;
|
||||
s === 1;
|
||||
~~~~~~~
|
||||
!!! error TS2365: Operator '===' cannot be applied to types 'symbol' and '1'.
|
||||
!!! error TS2365: Operator '===' cannot be applied to types 'symbol' and 'number'.
|
||||
s !== s;
|
||||
false !== s;
|
||||
~~~~~~~~~~~
|
||||
!!! error TS2365: Operator '!==' cannot be applied to types 'false' and 'symbol'.
|
||||
!!! error TS2365: Operator '!==' cannot be applied to types 'boolean' and 'symbol'.
|
Loading…
Reference in a new issue