Skip to content

Commit cb9be66

Browse files
committed
Merge pull request #8452 from Microsoft/equalityUndefinedAndNull
Allow equality comparisons to undefined and null in strict null checking mode
2 parents 7f82beb + e828fce commit cb9be66

File tree

4 files changed

+299
-4
lines changed

4 files changed

+299
-4
lines changed

src/compiler/checker.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12053,6 +12053,10 @@ namespace ts {
1205312053
return sourceType;
1205412054
}
1205512055

12056+
function isTypeEqualityComparableTo(source: Type, target: Type) {
12057+
return (target.flags & TypeFlags.Nullable) !== 0 || isTypeComparableTo(source, target);
12058+
}
12059+
1205612060
function checkBinaryExpression(node: BinaryExpression, contextualMapper?: TypeMapper) {
1205712061
return checkBinaryLikeExpression(node.left, node.operatorToken, node.right, contextualMapper, node);
1205812062
}
@@ -12166,15 +12170,17 @@ namespace ts {
1216612170
case SyntaxKind.GreaterThanToken:
1216712171
case SyntaxKind.LessThanEqualsToken:
1216812172
case SyntaxKind.GreaterThanEqualsToken:
12169-
if (!checkForDisallowedESSymbolOperand(operator)) {
12170-
return booleanType;
12173+
if (checkForDisallowedESSymbolOperand(operator)) {
12174+
if (!isTypeComparableTo(leftType, rightType) && !isTypeComparableTo(rightType, leftType)) {
12175+
reportOperatorError();
12176+
}
1217112177
}
12172-
// Fall through
12178+
return booleanType;
1217312179
case SyntaxKind.EqualsEqualsToken:
1217412180
case SyntaxKind.ExclamationEqualsToken:
1217512181
case SyntaxKind.EqualsEqualsEqualsToken:
1217612182
case SyntaxKind.ExclamationEqualsEqualsToken:
12177-
if (!isTypeComparableTo(leftType, rightType) && !isTypeComparableTo(rightType, leftType)) {
12183+
if (!isTypeEqualityComparableTo(leftType, rightType) && !isTypeEqualityComparableTo(rightType, leftType)) {
1217812184
reportOperatorError();
1217912185
}
1218012186
return booleanType;
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
tests/cases/conformance/types/typeRelationships/comparable/equalityStrictNulls.ts(60,9): error TS2365: Operator '>' cannot be applied to types 'number' and 'undefined'.
2+
tests/cases/conformance/types/typeRelationships/comparable/equalityStrictNulls.ts(62,9): error TS2365: Operator '<' cannot be applied to types 'number' and 'undefined'.
3+
tests/cases/conformance/types/typeRelationships/comparable/equalityStrictNulls.ts(64,9): error TS2365: Operator '>=' cannot be applied to types 'number' and 'undefined'.
4+
tests/cases/conformance/types/typeRelationships/comparable/equalityStrictNulls.ts(66,9): error TS2365: Operator '<=' cannot be applied to types 'number' and 'undefined'.
5+
6+
7+
==== tests/cases/conformance/types/typeRelationships/comparable/equalityStrictNulls.ts (4 errors) ====
8+
9+
function f1(x: string) {
10+
if (x == undefined) {
11+
}
12+
if (x != undefined) {
13+
}
14+
if (x === undefined) {
15+
}
16+
if (x !== undefined) {
17+
}
18+
if (x == null) {
19+
}
20+
if (x != null) {
21+
}
22+
if (x === null) {
23+
}
24+
if (x !== null) {
25+
}
26+
if (undefined == x) {
27+
}
28+
if (undefined != x) {
29+
}
30+
if (undefined === x) {
31+
}
32+
if (undefined !== x) {
33+
}
34+
if (null == x) {
35+
}
36+
if (null != x) {
37+
}
38+
if (null === x) {
39+
}
40+
if (null !== x) {
41+
}
42+
}
43+
44+
function f2() {
45+
if (undefined == undefined) {
46+
}
47+
if (undefined == null) {
48+
}
49+
if (null == undefined) {
50+
}
51+
if (null == null) {
52+
}
53+
}
54+
55+
function f3(a: number, b: boolean, c: { x: number }, d: number | string) {
56+
if (a == null) {
57+
}
58+
if (b == null) {
59+
}
60+
if (c == null) {
61+
}
62+
if (d == null) {
63+
}
64+
}
65+
66+
function f4(x: number) {
67+
if (x > undefined) {
68+
~~~~~~~~~~~~~
69+
!!! error TS2365: Operator '>' cannot be applied to types 'number' and 'undefined'.
70+
}
71+
if (x < undefined) {
72+
~~~~~~~~~~~~~
73+
!!! error TS2365: Operator '<' cannot be applied to types 'number' and 'undefined'.
74+
}
75+
if (x >= undefined) {
76+
~~~~~~~~~~~~~~
77+
!!! error TS2365: Operator '>=' cannot be applied to types 'number' and 'undefined'.
78+
}
79+
if (x <= undefined) {
80+
~~~~~~~~~~~~~~
81+
!!! error TS2365: Operator '<=' cannot be applied to types 'number' and 'undefined'.
82+
}
83+
}
84+
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
//// [equalityStrictNulls.ts]
2+
3+
function f1(x: string) {
4+
if (x == undefined) {
5+
}
6+
if (x != undefined) {
7+
}
8+
if (x === undefined) {
9+
}
10+
if (x !== undefined) {
11+
}
12+
if (x == null) {
13+
}
14+
if (x != null) {
15+
}
16+
if (x === null) {
17+
}
18+
if (x !== null) {
19+
}
20+
if (undefined == x) {
21+
}
22+
if (undefined != x) {
23+
}
24+
if (undefined === x) {
25+
}
26+
if (undefined !== x) {
27+
}
28+
if (null == x) {
29+
}
30+
if (null != x) {
31+
}
32+
if (null === x) {
33+
}
34+
if (null !== x) {
35+
}
36+
}
37+
38+
function f2() {
39+
if (undefined == undefined) {
40+
}
41+
if (undefined == null) {
42+
}
43+
if (null == undefined) {
44+
}
45+
if (null == null) {
46+
}
47+
}
48+
49+
function f3(a: number, b: boolean, c: { x: number }, d: number | string) {
50+
if (a == null) {
51+
}
52+
if (b == null) {
53+
}
54+
if (c == null) {
55+
}
56+
if (d == null) {
57+
}
58+
}
59+
60+
function f4(x: number) {
61+
if (x > undefined) {
62+
}
63+
if (x < undefined) {
64+
}
65+
if (x >= undefined) {
66+
}
67+
if (x <= undefined) {
68+
}
69+
}
70+
71+
72+
//// [equalityStrictNulls.js]
73+
function f1(x) {
74+
if (x == undefined) {
75+
}
76+
if (x != undefined) {
77+
}
78+
if (x === undefined) {
79+
}
80+
if (x !== undefined) {
81+
}
82+
if (x == null) {
83+
}
84+
if (x != null) {
85+
}
86+
if (x === null) {
87+
}
88+
if (x !== null) {
89+
}
90+
if (undefined == x) {
91+
}
92+
if (undefined != x) {
93+
}
94+
if (undefined === x) {
95+
}
96+
if (undefined !== x) {
97+
}
98+
if (null == x) {
99+
}
100+
if (null != x) {
101+
}
102+
if (null === x) {
103+
}
104+
if (null !== x) {
105+
}
106+
}
107+
function f2() {
108+
if (undefined == undefined) {
109+
}
110+
if (undefined == null) {
111+
}
112+
if (null == undefined) {
113+
}
114+
if (null == null) {
115+
}
116+
}
117+
function f3(a, b, c, d) {
118+
if (a == null) {
119+
}
120+
if (b == null) {
121+
}
122+
if (c == null) {
123+
}
124+
if (d == null) {
125+
}
126+
}
127+
function f4(x) {
128+
if (x > undefined) {
129+
}
130+
if (x < undefined) {
131+
}
132+
if (x >= undefined) {
133+
}
134+
if (x <= undefined) {
135+
}
136+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// @strictNullChecks: true
2+
3+
function f1(x: string) {
4+
if (x == undefined) {
5+
}
6+
if (x != undefined) {
7+
}
8+
if (x === undefined) {
9+
}
10+
if (x !== undefined) {
11+
}
12+
if (x == null) {
13+
}
14+
if (x != null) {
15+
}
16+
if (x === null) {
17+
}
18+
if (x !== null) {
19+
}
20+
if (undefined == x) {
21+
}
22+
if (undefined != x) {
23+
}
24+
if (undefined === x) {
25+
}
26+
if (undefined !== x) {
27+
}
28+
if (null == x) {
29+
}
30+
if (null != x) {
31+
}
32+
if (null === x) {
33+
}
34+
if (null !== x) {
35+
}
36+
}
37+
38+
function f2() {
39+
if (undefined == undefined) {
40+
}
41+
if (undefined == null) {
42+
}
43+
if (null == undefined) {
44+
}
45+
if (null == null) {
46+
}
47+
}
48+
49+
function f3(a: number, b: boolean, c: { x: number }, d: number | string) {
50+
if (a == null) {
51+
}
52+
if (b == null) {
53+
}
54+
if (c == null) {
55+
}
56+
if (d == null) {
57+
}
58+
}
59+
60+
function f4(x: number) {
61+
if (x > undefined) {
62+
}
63+
if (x < undefined) {
64+
}
65+
if (x >= undefined) {
66+
}
67+
if (x <= undefined) {
68+
}
69+
}

0 commit comments

Comments
 (0)