Skip to content

Commit fb2ddd2

Browse files
jespinohahmadia
andcommitted
Fixes microsoft#32798: Narrow unkown to null|unknown type on == null guard
Co-authored-by: Hossein <[email protected]>
1 parent 541e553 commit fb2ddd2

File tree

6 files changed

+60
-9
lines changed

6 files changed

+60
-9
lines changed

src/compiler/checker.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23686,6 +23686,9 @@ namespace ts {
2368623686
assumeTrue = !assumeTrue;
2368723687
}
2368823688
const valueType = getTypeOfExpression(value);
23689+
if ((type.flags & TypeFlags.Unknown) && (operator === SyntaxKind.EqualsEqualsToken) && (valueType.flags & TypeFlags.Null)) {
23690+
return getUnionType([nullType, undefinedType]);
23691+
}
2368923692
if ((type.flags & TypeFlags.Unknown) && assumeTrue && (operator === SyntaxKind.EqualsEqualsEqualsToken || operator === SyntaxKind.ExclamationEqualsEqualsToken)) {
2369023693
if (valueType.flags & (TypeFlags.Primitive | TypeFlags.NonPrimitive)) {
2369123694
return valueType;

tests/baselines/reference/narrowByEquality.errors.txt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
tests/cases/compiler/narrowByEquality.ts(53,15): error TS2322: Type 'string | number' is not assignable to type 'number'.
1+
tests/cases/compiler/narrowByEquality.ts(60,15): error TS2322: Type 'string | number' is not assignable to type 'number'.
22
Type 'string' is not assignable to type 'number'.
3-
tests/cases/compiler/narrowByEquality.ts(54,9): error TS2322: Type 'string | number' is not assignable to type 'number'.
3+
tests/cases/compiler/narrowByEquality.ts(61,9): error TS2322: Type 'string | number' is not assignable to type 'number'.
44
Type 'string' is not assignable to type 'number'.
55

66

@@ -53,6 +53,13 @@ tests/cases/compiler/narrowByEquality.ts(54,9): error TS2322: Type 'string | num
5353
xAndObj;
5454
}
5555

56+
// From issue #32798
57+
declare let xUnknown: unknown
58+
59+
if (xUnknown == null) {
60+
xUnknown;
61+
}
62+
5663
// Repro from #24991
5764

5865
function test(level: number | string):number {

tests/baselines/reference/narrowByEquality.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,13 @@ if (x == xAndObj) {
4747
xAndObj;
4848
}
4949

50+
// From issue #32798
51+
declare let xUnknown: unknown
52+
53+
if (xUnknown == null) {
54+
xUnknown;
55+
}
56+
5057
// Repro from #24991
5158

5259
function test(level: number | string):number {
@@ -91,6 +98,9 @@ if (x == xAndObj) {
9198
x;
9299
xAndObj;
93100
}
101+
if (xUnknown == null) {
102+
xUnknown;
103+
}
94104
// Repro from #24991
95105
function test(level) {
96106
if (level == +level) {

tests/baselines/reference/narrowByEquality.symbols

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -91,22 +91,33 @@ if (x == xAndObj) {
9191
>xAndObj : Symbol(xAndObj, Decl(narrowByEquality.ts, 37, 11))
9292
}
9393

94+
// From issue #32798
95+
declare let xUnknown: unknown
96+
>xUnknown : Symbol(xUnknown, Decl(narrowByEquality.ts, 49, 11))
97+
98+
if (xUnknown == null) {
99+
>xUnknown : Symbol(xUnknown, Decl(narrowByEquality.ts, 49, 11))
100+
101+
xUnknown;
102+
>xUnknown : Symbol(xUnknown, Decl(narrowByEquality.ts, 49, 11))
103+
}
104+
94105
// Repro from #24991
95106

96107
function test(level: number | string):number {
97-
>test : Symbol(test, Decl(narrowByEquality.ts, 46, 1))
98-
>level : Symbol(level, Decl(narrowByEquality.ts, 50, 14))
108+
>test : Symbol(test, Decl(narrowByEquality.ts, 53, 1))
109+
>level : Symbol(level, Decl(narrowByEquality.ts, 57, 14))
99110

100111
if (level == +level) {
101-
>level : Symbol(level, Decl(narrowByEquality.ts, 50, 14))
102-
>level : Symbol(level, Decl(narrowByEquality.ts, 50, 14))
112+
>level : Symbol(level, Decl(narrowByEquality.ts, 57, 14))
113+
>level : Symbol(level, Decl(narrowByEquality.ts, 57, 14))
103114

104115
const q2: number = level; // error
105-
>q2 : Symbol(q2, Decl(narrowByEquality.ts, 52, 13))
106-
>level : Symbol(level, Decl(narrowByEquality.ts, 50, 14))
116+
>q2 : Symbol(q2, Decl(narrowByEquality.ts, 59, 13))
117+
>level : Symbol(level, Decl(narrowByEquality.ts, 57, 14))
107118

108119
return level;
109-
>level : Symbol(level, Decl(narrowByEquality.ts, 50, 14))
120+
>level : Symbol(level, Decl(narrowByEquality.ts, 57, 14))
110121
}
111122
return 0;
112123
}

tests/baselines/reference/narrowByEquality.types

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,19 @@ if (x == xAndObj) {
107107
>xAndObj : string | number | boolean
108108
}
109109

110+
// From issue #32798
111+
declare let xUnknown: unknown
112+
>xUnknown : unknown
113+
114+
if (xUnknown == null) {
115+
>xUnknown == null : boolean
116+
>xUnknown : unknown
117+
>null : null
118+
119+
xUnknown;
120+
>xUnknown : null | undefined
121+
}
122+
110123
// Repro from #24991
111124

112125
function test(level: number | string):number {

tests/cases/compiler/narrowByEquality.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@ if (x == xAndObj) {
4848
xAndObj;
4949
}
5050

51+
// From issue #32798
52+
declare let xUnknown: unknown
53+
54+
if (xUnknown == null) {
55+
xUnknown;
56+
}
57+
5158
// Repro from #24991
5259

5360
function test(level: number | string):number {

0 commit comments

Comments
 (0)