-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Improve comparison operators type checking to disallow unions containing numbers as an operand #52048
Merged
RyanCavanaugh
merged 1 commit into
microsoft:main
from
Andarist:comparison-operator-improvements
Jan 20, 2023
Merged
Improve comparison operators type checking to disallow unions containing numbers as an operand #52048
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,9 +6,41 @@ tests/cases/conformance/expressions/binaryOperators/comparisonOperator/compariso | |
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNoRelationshipTypeParameter.ts(17,14): error TS2367: This comparison appears to be unintentional because the types 'T' and 'U' have no overlap. | ||
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNoRelationshipTypeParameter.ts(18,14): error TS2367: This comparison appears to be unintentional because the types 'T' and 'U' have no overlap. | ||
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNoRelationshipTypeParameter.ts(19,14): error TS2367: This comparison appears to be unintentional because the types 'T' and 'U' have no overlap. | ||
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNoRelationshipTypeParameter.ts(23,16): error TS2365: Operator '<' cannot be applied to types 'T' and 'number'. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To bring back the old behavior we should probably also allow unconstrained generics - but I wasn't sure what's the best check for them. Should I just check |
||
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNoRelationshipTypeParameter.ts(26,16): error TS2365: Operator '<' cannot be applied to types 'T' and 'E'. | ||
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNoRelationshipTypeParameter.ts(31,16): error TS2365: Operator '<' cannot be applied to types 'number' and 'T'. | ||
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNoRelationshipTypeParameter.ts(34,16): error TS2365: Operator '<' cannot be applied to types 'E' and 'T'. | ||
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNoRelationshipTypeParameter.ts(40,16): error TS2365: Operator '<' cannot be applied to types 'T' and 'number'. | ||
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNoRelationshipTypeParameter.ts(43,16): error TS2365: Operator '<' cannot be applied to types 'T' and 'E'. | ||
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNoRelationshipTypeParameter.ts(48,16): error TS2365: Operator '<' cannot be applied to types 'number' and 'T'. | ||
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNoRelationshipTypeParameter.ts(51,16): error TS2365: Operator '<' cannot be applied to types 'E' and 'T'. | ||
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNoRelationshipTypeParameter.ts(57,16): error TS2365: Operator '<' cannot be applied to types 'T' and 'number'. | ||
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNoRelationshipTypeParameter.ts(60,16): error TS2365: Operator '<' cannot be applied to types 'T' and 'E'. | ||
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNoRelationshipTypeParameter.ts(65,16): error TS2365: Operator '<' cannot be applied to types 'number' and 'T'. | ||
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNoRelationshipTypeParameter.ts(68,16): error TS2365: Operator '<' cannot be applied to types 'E' and 'T'. | ||
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNoRelationshipTypeParameter.ts(74,16): error TS2365: Operator '<' cannot be applied to types 'T' and 'number'. | ||
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNoRelationshipTypeParameter.ts(77,16): error TS2365: Operator '<' cannot be applied to types 'T' and 'E'. | ||
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNoRelationshipTypeParameter.ts(82,16): error TS2365: Operator '<' cannot be applied to types 'number' and 'T'. | ||
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNoRelationshipTypeParameter.ts(85,16): error TS2365: Operator '<' cannot be applied to types 'E' and 'T'. | ||
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNoRelationshipTypeParameter.ts(91,16): error TS2365: Operator '<' cannot be applied to types 'T' and 'number'. | ||
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNoRelationshipTypeParameter.ts(94,16): error TS2365: Operator '<' cannot be applied to types 'T' and 'E'. | ||
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNoRelationshipTypeParameter.ts(99,16): error TS2365: Operator '<' cannot be applied to types 'number' and 'T'. | ||
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNoRelationshipTypeParameter.ts(102,16): error TS2365: Operator '<' cannot be applied to types 'E' and 'T'. | ||
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNoRelationshipTypeParameter.ts(108,16): error TS2365: Operator '<' cannot be applied to types 'T' and 'number'. | ||
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNoRelationshipTypeParameter.ts(111,16): error TS2365: Operator '<' cannot be applied to types 'T' and 'E'. | ||
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNoRelationshipTypeParameter.ts(116,16): error TS2365: Operator '<' cannot be applied to types 'number' and 'T'. | ||
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNoRelationshipTypeParameter.ts(119,16): error TS2365: Operator '<' cannot be applied to types 'E' and 'T'. | ||
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNoRelationshipTypeParameter.ts(125,16): error TS2365: Operator '<' cannot be applied to types 'T' and 'number'. | ||
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNoRelationshipTypeParameter.ts(128,16): error TS2365: Operator '<' cannot be applied to types 'T' and 'E'. | ||
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNoRelationshipTypeParameter.ts(133,16): error TS2365: Operator '<' cannot be applied to types 'number' and 'T'. | ||
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNoRelationshipTypeParameter.ts(136,16): error TS2365: Operator '<' cannot be applied to types 'E' and 'T'. | ||
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNoRelationshipTypeParameter.ts(142,16): error TS2365: Operator '<' cannot be applied to types 'T' and 'number'. | ||
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNoRelationshipTypeParameter.ts(145,16): error TS2365: Operator '<' cannot be applied to types 'T' and 'E'. | ||
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNoRelationshipTypeParameter.ts(150,16): error TS2365: Operator '<' cannot be applied to types 'number' and 'T'. | ||
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNoRelationshipTypeParameter.ts(153,16): error TS2365: Operator '<' cannot be applied to types 'E' and 'T'. | ||
|
||
|
||
==== tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNoRelationshipTypeParameter.ts (8 errors) ==== | ||
==== tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNoRelationshipTypeParameter.ts (40 errors) ==== | ||
enum E { a, b, c } | ||
|
||
var a: boolean; | ||
|
@@ -48,136 +80,200 @@ tests/cases/conformance/expressions/binaryOperators/comparisonOperator/compariso | |
// operator < | ||
var r1a1 = t < a; | ||
var r1a2 = t < b; | ||
~~~~~ | ||
!!! error TS2365: Operator '<' cannot be applied to types 'T' and 'number'. | ||
var r1a3 = t < c; | ||
var r1a4 = t < d; | ||
var r1a5 = t < e; | ||
~~~~~ | ||
!!! error TS2365: Operator '<' cannot be applied to types 'T' and 'E'. | ||
var r1a6 = t < f; | ||
var r1a7 = t < g; | ||
|
||
var r1b1 = a < t; | ||
var r1b2 = b < t; | ||
~~~~~ | ||
!!! error TS2365: Operator '<' cannot be applied to types 'number' and 'T'. | ||
var r1b3 = c < t; | ||
var r1b4 = d < t; | ||
var r1b5 = e < t; | ||
~~~~~ | ||
!!! error TS2365: Operator '<' cannot be applied to types 'E' and 'T'. | ||
var r1b6 = f < t; | ||
var r1b7 = g < t; | ||
|
||
// operator > | ||
var r2a1 = t < a; | ||
var r2a2 = t < b; | ||
~~~~~ | ||
!!! error TS2365: Operator '<' cannot be applied to types 'T' and 'number'. | ||
var r2a3 = t < c; | ||
var r2a4 = t < d; | ||
var r2a5 = t < e; | ||
~~~~~ | ||
!!! error TS2365: Operator '<' cannot be applied to types 'T' and 'E'. | ||
var r2a6 = t < f; | ||
var r2a7 = t < g; | ||
|
||
var r2b1 = a < t; | ||
var r2b2 = b < t; | ||
~~~~~ | ||
!!! error TS2365: Operator '<' cannot be applied to types 'number' and 'T'. | ||
var r2b3 = c < t; | ||
var r2b4 = d < t; | ||
var r2b5 = e < t; | ||
~~~~~ | ||
!!! error TS2365: Operator '<' cannot be applied to types 'E' and 'T'. | ||
var r2b6 = f < t; | ||
var r2b7 = g < t; | ||
|
||
// operator <= | ||
var r3a1 = t < a; | ||
var r3a2 = t < b; | ||
~~~~~ | ||
!!! error TS2365: Operator '<' cannot be applied to types 'T' and 'number'. | ||
var r3a3 = t < c; | ||
var r3a4 = t < d; | ||
var r3a5 = t < e; | ||
~~~~~ | ||
!!! error TS2365: Operator '<' cannot be applied to types 'T' and 'E'. | ||
var r3a6 = t < f; | ||
var r3a7 = t < g; | ||
|
||
var r3b1 = a < t; | ||
var r3b2 = b < t; | ||
~~~~~ | ||
!!! error TS2365: Operator '<' cannot be applied to types 'number' and 'T'. | ||
var r3b3 = c < t; | ||
var r3b4 = d < t; | ||
var r3b5 = e < t; | ||
~~~~~ | ||
!!! error TS2365: Operator '<' cannot be applied to types 'E' and 'T'. | ||
var r3b6 = f < t; | ||
var r3b7 = g < t; | ||
|
||
// operator >= | ||
var r4a1 = t < a; | ||
var r4a2 = t < b; | ||
~~~~~ | ||
!!! error TS2365: Operator '<' cannot be applied to types 'T' and 'number'. | ||
var r4a3 = t < c; | ||
var r4a4 = t < d; | ||
var r4a5 = t < e; | ||
~~~~~ | ||
!!! error TS2365: Operator '<' cannot be applied to types 'T' and 'E'. | ||
var r4a6 = t < f; | ||
var r4a7 = t < g; | ||
|
||
var r4b1 = a < t; | ||
var r4b2 = b < t; | ||
~~~~~ | ||
!!! error TS2365: Operator '<' cannot be applied to types 'number' and 'T'. | ||
var r4b3 = c < t; | ||
var r4b4 = d < t; | ||
var r4b5 = e < t; | ||
~~~~~ | ||
!!! error TS2365: Operator '<' cannot be applied to types 'E' and 'T'. | ||
var r4b6 = f < t; | ||
var r4b7 = g < t; | ||
|
||
// operator == | ||
var r5a1 = t < a; | ||
var r5a2 = t < b; | ||
~~~~~ | ||
!!! error TS2365: Operator '<' cannot be applied to types 'T' and 'number'. | ||
var r5a3 = t < c; | ||
var r5a4 = t < d; | ||
var r5a5 = t < e; | ||
~~~~~ | ||
!!! error TS2365: Operator '<' cannot be applied to types 'T' and 'E'. | ||
var r5a6 = t < f; | ||
var r5a7 = t < g; | ||
|
||
var r5b1 = a < t; | ||
var r5b2 = b < t; | ||
~~~~~ | ||
!!! error TS2365: Operator '<' cannot be applied to types 'number' and 'T'. | ||
var r5b3 = c < t; | ||
var r5b4 = d < t; | ||
var r5b5 = e < t; | ||
~~~~~ | ||
!!! error TS2365: Operator '<' cannot be applied to types 'E' and 'T'. | ||
var r5b6 = f < t; | ||
var r5b7 = g < t; | ||
|
||
// operator != | ||
var r6a1 = t < a; | ||
var r6a2 = t < b; | ||
~~~~~ | ||
!!! error TS2365: Operator '<' cannot be applied to types 'T' and 'number'. | ||
var r6a3 = t < c; | ||
var r6a4 = t < d; | ||
var r6a5 = t < e; | ||
~~~~~ | ||
!!! error TS2365: Operator '<' cannot be applied to types 'T' and 'E'. | ||
var r6a6 = t < f; | ||
var r6a7 = t < g; | ||
|
||
var r6b1 = a < t; | ||
var r6b2 = b < t; | ||
~~~~~ | ||
!!! error TS2365: Operator '<' cannot be applied to types 'number' and 'T'. | ||
var r6b3 = c < t; | ||
var r6b4 = d < t; | ||
var r6b5 = e < t; | ||
~~~~~ | ||
!!! error TS2365: Operator '<' cannot be applied to types 'E' and 'T'. | ||
var r6b6 = f < t; | ||
var r6b7 = g < t; | ||
|
||
// operator === | ||
var r7a1 = t < a; | ||
var r7a2 = t < b; | ||
~~~~~ | ||
!!! error TS2365: Operator '<' cannot be applied to types 'T' and 'number'. | ||
var r7a3 = t < c; | ||
var r7a4 = t < d; | ||
var r7a5 = t < e; | ||
~~~~~ | ||
!!! error TS2365: Operator '<' cannot be applied to types 'T' and 'E'. | ||
var r7a6 = t < f; | ||
var r7a7 = t < g; | ||
|
||
var r7b1 = a < t; | ||
var r7b2 = b < t; | ||
~~~~~ | ||
!!! error TS2365: Operator '<' cannot be applied to types 'number' and 'T'. | ||
var r7b3 = c < t; | ||
var r7b4 = d < t; | ||
var r7b5 = e < t; | ||
~~~~~ | ||
!!! error TS2365: Operator '<' cannot be applied to types 'E' and 'T'. | ||
var r7b6 = f < t; | ||
var r7b7 = g < t; | ||
|
||
// operator !== | ||
var r8a1 = t < a; | ||
var r8a2 = t < b; | ||
~~~~~ | ||
!!! error TS2365: Operator '<' cannot be applied to types 'T' and 'number'. | ||
var r8a3 = t < c; | ||
var r8a4 = t < d; | ||
var r8a5 = t < e; | ||
~~~~~ | ||
!!! error TS2365: Operator '<' cannot be applied to types 'T' and 'E'. | ||
var r8a6 = t < f; | ||
var r8a7 = t < g; | ||
|
||
var r8b1 = a < t; | ||
var r8b2 = b < t; | ||
~~~~~ | ||
!!! error TS2365: Operator '<' cannot be applied to types 'number' and 'T'. | ||
var r8b3 = c < t; | ||
var r8b4 = d < t; | ||
var r8b5 = e < t; | ||
~~~~~ | ||
!!! error TS2365: Operator '<' cannot be applied to types 'E' and 'T'. | ||
var r8b6 = f < t; | ||
var r8b7 = g < t; | ||
} |
11 changes: 11 additions & 0 deletions
11
tests/baselines/reference/comparisonOperatorWithNumberOperand.errors.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNumberOperand.ts(3,1): error TS2365: Operator '>=' cannot be applied to types 'number | Promise<number>' and 'number'. | ||
|
||
|
||
==== tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNumberOperand.ts (1 errors) ==== | ||
// repro #52036 | ||
declare const t1: number | Promise<number> | ||
t1 >= 0 // error | ||
~~~~~~~ | ||
!!! error TS2365: Operator '>=' cannot be applied to types 'number | Promise<number>' and 'number'. | ||
!!! related TS2773 tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNumberOperand.ts:3:1: Did you forget to use 'await'? | ||
|
9 changes: 9 additions & 0 deletions
9
tests/baselines/reference/comparisonOperatorWithNumberOperand.symbols
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
=== tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNumberOperand.ts === | ||
// repro #52036 | ||
declare const t1: number | Promise<number> | ||
>t1 : Symbol(t1, Decl(comparisonOperatorWithNumberOperand.ts, 1, 13)) | ||
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --)) | ||
|
||
t1 >= 0 // error | ||
>t1 : Symbol(t1, Decl(comparisonOperatorWithNumberOperand.ts, 1, 13)) | ||
|
10 changes: 10 additions & 0 deletions
10
tests/baselines/reference/comparisonOperatorWithNumberOperand.types
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
=== tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithNumberOperand.ts === | ||
// repro #52036 | ||
declare const t1: number | Promise<number> | ||
>t1 : number | Promise<number> | ||
|
||
t1 >= 0 // error | ||
>t1 >= 0 : boolean | ||
>t1 : number | Promise<number> | ||
>0 : 0 | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
essentially, when one of the operands is assignable to a number (or big int) then we require the other one to be assignable to it too.
areTypesComparable
kicks in only when both sides are not assignable tonumberOrBigIntType