Skip to content

Flag non-any/number/string operands on either side of comparison as errors #27926

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 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) ||
Copy link
Member

@weswigham weswigham Jan 30, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm pretty sure all these comparisons should be using & and not ===. I'm also curious why NumberLiteral (and BigIntLiteral) is missing - I'd assume comparing 0 and 2 (and 0n and 2n) is probably OK.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd definitely like to see some tests comparing numeric literal types of all sorts among one another and with their bases (number, bigint).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have lots of troubles adapting the tests. I prefer to give up on this PR :(

(t === TypeFlags.Number) ||
(t === TypeFlags.Any) ||
(t === TypeFlags.TypeParameter) ||
(t === TypeFlags.Enum) ||
(t === TypeFlags.Object) ||
(t === TypeFlags.Intersection) ||
(t === (TypeFlags.EnumLiteral | TypeFlags.Union)) ||
(t === (TypeFlags.Union));
}

function checkAssignmentDeclaration(kind: AssignmentDeclarationKind, rightType: Type) {
if (kind === AssignmentDeclarationKind.ModuleExports) {
for (const prop of getPropertiesOfObjectType(rightType)) {
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