Skip to content

Commit 2b43e5b

Browse files
committed
Flag non-any/number/string operands on either side of comparison as errors
Fixes microsoft#15506
1 parent e4f3b23 commit 2b43e5b

File tree

2 files changed

+43
-4
lines changed

2 files changed

+43
-4
lines changed

src/compiler/checker.ts

+18-3
Original file line numberDiff line numberDiff line change
@@ -22698,8 +22698,10 @@ namespace ts {
2269822698
if (checkForDisallowedESSymbolOperand(operator)) {
2269922699
leftType = getBaseTypeOfLiteralType(checkNonNullType(leftType, left));
2270022700
rightType = getBaseTypeOfLiteralType(checkNonNullType(rightType, right));
22701-
if (!(isTypeComparableTo(leftType, rightType) || isTypeComparableTo(rightType, leftType) ||
22702-
(isTypeAssignableTo(leftType, numberOrBigIntType) && isTypeAssignableTo(rightType, numberOrBigIntType))
22701+
if (!checkTypeComparableWithLessOrGreaterThanOperator(leftType) &&
22702+
!checkTypeComparableWithLessOrGreaterThanOperator(rightType) ||
22703+
!(isTypeComparableTo(leftType, rightType) || isTypeComparableTo(rightType, leftType) ||
22704+
(isTypeAssignableTo(leftType, numberOrBigIntType) && isTypeAssignableTo(rightType, numberOrBigIntType))
2270322705
)) {
2270422706
reportOperatorError();
2270522707
}
@@ -22760,6 +22762,19 @@ namespace ts {
2276022762
return Debug.fail();
2276122763
}
2276222764

22765+
function checkTypeComparableWithLessOrGreaterThanOperator(valueType: Type): boolean {
22766+
const t = valueType.flags;
22767+
return (t === TypeFlags.String) ||
22768+
(t === TypeFlags.Number) ||
22769+
(t === TypeFlags.Any) ||
22770+
(t === TypeFlags.TypeParameter) ||
22771+
(t === TypeFlags.Enum) ||
22772+
(t === TypeFlags.Object) ||
22773+
(t === TypeFlags.Intersection) ||
22774+
(t === (TypeFlags.EnumLiteral | TypeFlags.Union | TypeFlags.UnionOfPrimitiveTypes)) ||
22775+
(t === (TypeFlags.Union | TypeFlags.UnionOfPrimitiveTypes));
22776+
}
22777+
2276322778
function checkAssignmentDeclaration(kind: AssignmentDeclarationKind, rightType: Type) {
2276422779
if (kind === AssignmentDeclarationKind.ModuleExports) {
2276522780
for (const prop of getPropertiesOfObjectType(rightType)) {
@@ -22805,7 +22820,7 @@ namespace ts {
2280522820
case SyntaxKind.AmpersandToken:
2280622821
case SyntaxKind.AmpersandEqualsToken:
2280722822
return SyntaxKind.AmpersandAmpersandToken;
22808-
default:
22823+
default:
2280922824
return undefined;
2281022825
}
2281122826
}

tests/baselines/reference/comparisonOperatorWithIdenticalPrimitiveType.errors.txt

+25-1
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,30 @@
1+
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(11,11): error TS2365: Operator '<' cannot be applied to types 'boolean' and 'boolean'.
2+
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(13,11): error TS2365: Operator '<' cannot be applied to types 'void' and 'void'.
13
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(15,11): error TS2531: Object is possibly 'null'.
24
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(15,18): error TS2531: Object is possibly 'null'.
35
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(16,11): error TS2532: Object is possibly 'undefined'.
46
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(16,23): error TS2532: Object is possibly 'undefined'.
7+
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(20,11): error TS2365: Operator '>' cannot be applied to types 'boolean' and 'boolean'.
8+
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(22,11): error TS2365: Operator '>' cannot be applied to types 'void' and 'void'.
59
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(24,11): error TS2531: Object is possibly 'null'.
610
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(24,18): error TS2531: Object is possibly 'null'.
711
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(25,11): error TS2532: Object is possibly 'undefined'.
812
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(25,23): error TS2532: Object is possibly 'undefined'.
13+
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(29,11): error TS2365: Operator '<=' cannot be applied to types 'boolean' and 'boolean'.
14+
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(31,11): error TS2365: Operator '<=' cannot be applied to types 'void' and 'void'.
915
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(33,11): error TS2531: Object is possibly 'null'.
1016
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(33,19): error TS2531: Object is possibly 'null'.
1117
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(34,11): error TS2532: Object is possibly 'undefined'.
1218
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(34,24): error TS2532: Object is possibly 'undefined'.
19+
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(38,11): error TS2365: Operator '>=' cannot be applied to types 'boolean' and 'boolean'.
20+
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(40,11): error TS2365: Operator '>=' cannot be applied to types 'void' and 'void'.
1321
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(42,11): error TS2531: Object is possibly 'null'.
1422
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(42,19): error TS2531: Object is possibly 'null'.
1523
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(43,11): error TS2532: Object is possibly 'undefined'.
1624
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIdenticalPrimitiveType.ts(43,24): error TS2532: Object is possibly 'undefined'.
1725

1826

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

2230
var a: number;
@@ -28,8 +36,12 @@ tests/cases/conformance/expressions/binaryOperators/comparisonOperator/compariso
2836
// operator <
2937
var ra1 = a < a;
3038
var ra2 = b < b;
39+
~~~~~
40+
!!! error TS2365: Operator '<' cannot be applied to types 'boolean' and 'boolean'.
3141
var ra3 = c < c;
3242
var ra4 = d < d;
43+
~~~~~
44+
!!! error TS2365: Operator '<' cannot be applied to types 'void' and 'void'.
3345
var ra5 = e < e;
3446
var ra6 = null < null;
3547
~~~~
@@ -45,8 +57,12 @@ tests/cases/conformance/expressions/binaryOperators/comparisonOperator/compariso
4557
// operator >
4658
var rb1 = a > a;
4759
var rb2 = b > b;
60+
~~~~~
61+
!!! error TS2365: Operator '>' cannot be applied to types 'boolean' and 'boolean'.
4862
var rb3 = c > c;
4963
var rb4 = d > d;
64+
~~~~~
65+
!!! error TS2365: Operator '>' cannot be applied to types 'void' and 'void'.
5066
var rb5 = e > e;
5167
var rb6 = null > null;
5268
~~~~
@@ -62,8 +78,12 @@ tests/cases/conformance/expressions/binaryOperators/comparisonOperator/compariso
6278
// operator <=
6379
var rc1 = a <= a;
6480
var rc2 = b <= b;
81+
~~~~~~
82+
!!! error TS2365: Operator '<=' cannot be applied to types 'boolean' and 'boolean'.
6583
var rc3 = c <= c;
6684
var rc4 = d <= d;
85+
~~~~~~
86+
!!! error TS2365: Operator '<=' cannot be applied to types 'void' and 'void'.
6787
var rc5 = e <= e;
6888
var rc6 = null <= null;
6989
~~~~
@@ -79,8 +99,12 @@ tests/cases/conformance/expressions/binaryOperators/comparisonOperator/compariso
7999
// operator >=
80100
var rd1 = a >= a;
81101
var rd2 = b >= b;
102+
~~~~~~
103+
!!! error TS2365: Operator '>=' cannot be applied to types 'boolean' and 'boolean'.
82104
var rd3 = c >= c;
83105
var rd4 = d >= d;
106+
~~~~~~
107+
!!! error TS2365: Operator '>=' cannot be applied to types 'void' and 'void'.
84108
var rd5 = e >= e;
85109
var rd6 = null >= null;
86110
~~~~

0 commit comments

Comments
 (0)