Skip to content

Commit

Permalink
Flag non-any/number/string operands on either side of comparison as e…
Browse files Browse the repository at this point in the history
…rrors

Fixes #15506
  • Loading branch information
feloy committed Jan 30, 2019
1 parent e4f3b23 commit 2b43e5b
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 4 deletions.
21 changes: 18 additions & 3 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22698,8 +22698,10 @@ namespace ts {
if (checkForDisallowedESSymbolOperand(operator)) {
leftType = getBaseTypeOfLiteralType(checkNonNullType(leftType, left));
rightType = getBaseTypeOfLiteralType(checkNonNullType(rightType, right));
if (!(isTypeComparableTo(leftType, rightType) || isTypeComparableTo(rightType, leftType) ||
(isTypeAssignableTo(leftType, numberOrBigIntType) && isTypeAssignableTo(rightType, numberOrBigIntType))
if (!checkTypeComparableWithLessOrGreaterThanOperator(leftType) &&
!checkTypeComparableWithLessOrGreaterThanOperator(rightType) ||
!(isTypeComparableTo(leftType, rightType) || isTypeComparableTo(rightType, leftType) ||
(isTypeAssignableTo(leftType, numberOrBigIntType) && isTypeAssignableTo(rightType, numberOrBigIntType))
)) {
reportOperatorError();
}
Expand Down Expand Up @@ -22760,6 +22762,19 @@ namespace ts {
return Debug.fail();
}

function checkTypeComparableWithLessOrGreaterThanOperator(valueType: Type): boolean {
const t = valueType.flags;
return (t === TypeFlags.String) ||
(t === TypeFlags.Number) ||
(t === TypeFlags.Any) ||
(t === TypeFlags.TypeParameter) ||
(t === TypeFlags.Enum) ||
(t === TypeFlags.Object) ||
(t === TypeFlags.Intersection) ||
(t === (TypeFlags.EnumLiteral | TypeFlags.Union | TypeFlags.UnionOfPrimitiveTypes)) ||
(t === (TypeFlags.Union | TypeFlags.UnionOfPrimitiveTypes));
}

function checkAssignmentDeclaration(kind: AssignmentDeclarationKind, rightType: Type) {
if (kind === AssignmentDeclarationKind.ModuleExports) {
for (const prop of getPropertiesOfObjectType(rightType)) {
Expand Down Expand Up @@ -22805,7 +22820,7 @@ namespace ts {
case SyntaxKind.AmpersandToken:
case SyntaxKind.AmpersandEqualsToken:
return SyntaxKind.AmpersandAmpersandToken;
default:
default:
return undefined;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,30 @@
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(11,11): error TS2365: Operator '<' cannot be applied to types 'boolean' and 'boolean'.
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(13,11): error TS2365: Operator '<' cannot be applied to types 'void' and 'void'.
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(15,11): error TS2531: Object is possibly 'null'.
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(15,18): error TS2531: Object is possibly 'null'.
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(16,11): error TS2532: Object is possibly 'undefined'.
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(16,23): error TS2532: Object is possibly 'undefined'.
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(20,11): error TS2365: Operator '>' cannot be applied to types 'boolean' and 'boolean'.
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(22,11): error TS2365: Operator '>' cannot be applied to types 'void' and 'void'.
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(24,11): error TS2531: Object is possibly 'null'.
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(24,18): error TS2531: Object is possibly 'null'.
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(25,11): error TS2532: Object is possibly 'undefined'.
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(25,23): error TS2532: Object is possibly 'undefined'.
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(29,11): error TS2365: Operator '<=' cannot be applied to types 'boolean' and 'boolean'.
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(31,11): error TS2365: Operator '<=' cannot be applied to types 'void' and 'void'.
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(33,11): error TS2531: Object is possibly 'null'.
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(33,19): error TS2531: Object is possibly 'null'.
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(34,11): error TS2532: Object is possibly 'undefined'.
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(34,24): error TS2532: Object is possibly 'undefined'.
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(38,11): error TS2365: Operator '>=' cannot be applied to types 'boolean' and 'boolean'.
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(40,11): error TS2365: Operator '>=' cannot be applied to types 'void' and 'void'.
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(42,11): error TS2531: Object is possibly 'null'.
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(42,19): error TS2531: Object is possibly 'null'.
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(43,11): error TS2532: Object is possibly 'undefined'.
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(43,24): error TS2532: Object is possibly 'undefined'.


==== tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts (16 errors) ====
==== tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts (24 errors) ====
enum E { a, b, c }

var a: number;
Expand All @@ -28,8 +36,12 @@ tests/cases/conformance/expressions/binaryOperators/comparisonOperator/compariso
// operator <
var ra1 = a < a;
var ra2 = b < b;
~~~~~
!!! error TS2365: Operator '<' cannot be applied to types 'boolean' and 'boolean'.
var ra3 = c < c;
var ra4 = d < d;
~~~~~
!!! error TS2365: Operator '<' cannot be applied to types 'void' and 'void'.
var ra5 = e < e;
var ra6 = null < null;
~~~~
Expand All @@ -45,8 +57,12 @@ tests/cases/conformance/expressions/binaryOperators/comparisonOperator/compariso
// operator >
var rb1 = a > a;
var rb2 = b > b;
~~~~~
!!! error TS2365: Operator '>' cannot be applied to types 'boolean' and 'boolean'.
var rb3 = c > c;
var rb4 = d > d;
~~~~~
!!! error TS2365: Operator '>' cannot be applied to types 'void' and 'void'.
var rb5 = e > e;
var rb6 = null > null;
~~~~
Expand All @@ -62,8 +78,12 @@ tests/cases/conformance/expressions/binaryOperators/comparisonOperator/compariso
// operator <=
var rc1 = a <= a;
var rc2 = b <= b;
~~~~~~
!!! error TS2365: Operator '<=' cannot be applied to types 'boolean' and 'boolean'.
var rc3 = c <= c;
var rc4 = d <= d;
~~~~~~
!!! error TS2365: Operator '<=' cannot be applied to types 'void' and 'void'.
var rc5 = e <= e;
var rc6 = null <= null;
~~~~
Expand All @@ -79,8 +99,12 @@ tests/cases/conformance/expressions/binaryOperators/comparisonOperator/compariso
// operator >=
var rd1 = a >= a;
var rd2 = b >= b;
~~~~~~
!!! error TS2365: Operator '>=' cannot be applied to types 'boolean' and 'boolean'.
var rd3 = c >= c;
var rd4 = d >= d;
~~~~~~
!!! error TS2365: Operator '>=' cannot be applied to types 'void' and 'void'.
var rd5 = e >= e;
var rd6 = null >= null;
~~~~
Expand Down

0 comments on commit 2b43e5b

Please sign in to comment.