Skip to content

Commit 10870b4

Browse files
TypeScript Botandrewbranch
TypeScript Bot
andauthored
Cherry-pick PR microsoft#50592 into release-4.8 (microsoft#50596)
Component commits: 46ce0b2 Use bidirectional comparability (aka comparability) in narrowing 3e227f7 Rename test, check other CFA branch, test without strictNullChecks Co-authored-by: Andrew Branch <[email protected]>
1 parent 502a908 commit 10870b4

8 files changed

+207
-1
lines changed

src/compiler/checker.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -25063,7 +25063,7 @@ namespace ts {
2506325063
const narrowedPropType = narrowType(propType);
2506425064
return filterType(type, t => {
2506525065
const discriminantType = getTypeOfPropertyOrIndexSignature(t, propName);
25066-
return !(narrowedPropType.flags & TypeFlags.Never) && isTypeComparableTo(narrowedPropType, discriminantType);
25066+
return !(narrowedPropType.flags & TypeFlags.Never) && areTypesComparable(narrowedPropType, discriminantType);
2506725067
});
2506825068
}
2506925069

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//// [undefinedAsDiscriminantWithUnknown.ts]
2+
type S =
3+
| { type: 'string', value: string }
4+
| { type: 'number', value: number }
5+
| { type: 'unknown', value: unknown }
6+
| { value: undefined };
7+
8+
declare var s: S
9+
10+
if (s.value !== undefined) {
11+
s;
12+
}
13+
else {
14+
s;
15+
}
16+
17+
//// [undefinedAsDiscriminantWithUnknown.js]
18+
if (s.value !== undefined) {
19+
s;
20+
}
21+
else {
22+
s;
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
=== tests/cases/compiler/undefinedAsDiscriminantWithUnknown.ts ===
2+
type S =
3+
>S : Symbol(S, Decl(undefinedAsDiscriminantWithUnknown.ts, 0, 0))
4+
5+
| { type: 'string', value: string }
6+
>type : Symbol(type, Decl(undefinedAsDiscriminantWithUnknown.ts, 1, 3))
7+
>value : Symbol(value, Decl(undefinedAsDiscriminantWithUnknown.ts, 1, 19))
8+
9+
| { type: 'number', value: number }
10+
>type : Symbol(type, Decl(undefinedAsDiscriminantWithUnknown.ts, 2, 3))
11+
>value : Symbol(value, Decl(undefinedAsDiscriminantWithUnknown.ts, 2, 19))
12+
13+
| { type: 'unknown', value: unknown }
14+
>type : Symbol(type, Decl(undefinedAsDiscriminantWithUnknown.ts, 3, 3))
15+
>value : Symbol(value, Decl(undefinedAsDiscriminantWithUnknown.ts, 3, 20))
16+
17+
| { value: undefined };
18+
>value : Symbol(value, Decl(undefinedAsDiscriminantWithUnknown.ts, 4, 3))
19+
20+
declare var s: S
21+
>s : Symbol(s, Decl(undefinedAsDiscriminantWithUnknown.ts, 6, 11))
22+
>S : Symbol(S, Decl(undefinedAsDiscriminantWithUnknown.ts, 0, 0))
23+
24+
if (s.value !== undefined) {
25+
>s.value : Symbol(value, Decl(undefinedAsDiscriminantWithUnknown.ts, 1, 19), Decl(undefinedAsDiscriminantWithUnknown.ts, 2, 19), Decl(undefinedAsDiscriminantWithUnknown.ts, 3, 20), Decl(undefinedAsDiscriminantWithUnknown.ts, 4, 3))
26+
>s : Symbol(s, Decl(undefinedAsDiscriminantWithUnknown.ts, 6, 11))
27+
>value : Symbol(value, Decl(undefinedAsDiscriminantWithUnknown.ts, 1, 19), Decl(undefinedAsDiscriminantWithUnknown.ts, 2, 19), Decl(undefinedAsDiscriminantWithUnknown.ts, 3, 20), Decl(undefinedAsDiscriminantWithUnknown.ts, 4, 3))
28+
>undefined : Symbol(undefined)
29+
30+
s;
31+
>s : Symbol(s, Decl(undefinedAsDiscriminantWithUnknown.ts, 6, 11))
32+
}
33+
else {
34+
s;
35+
>s : Symbol(s, Decl(undefinedAsDiscriminantWithUnknown.ts, 6, 11))
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
=== tests/cases/compiler/undefinedAsDiscriminantWithUnknown.ts ===
2+
type S =
3+
>S : { type: 'string'; value: string; } | { type: 'number'; value: number; } | { type: 'unknown'; value: unknown; } | { value: undefined; }
4+
5+
| { type: 'string', value: string }
6+
>type : "string"
7+
>value : string
8+
9+
| { type: 'number', value: number }
10+
>type : "number"
11+
>value : number
12+
13+
| { type: 'unknown', value: unknown }
14+
>type : "unknown"
15+
>value : unknown
16+
17+
| { value: undefined };
18+
>value : undefined
19+
20+
declare var s: S
21+
>s : S
22+
23+
if (s.value !== undefined) {
24+
>s.value !== undefined : boolean
25+
>s.value : unknown
26+
>s : S
27+
>value : unknown
28+
>undefined : undefined
29+
30+
s;
31+
>s : S
32+
}
33+
else {
34+
s;
35+
>s : S
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//// [undefinedAsDiscriminantWithUnknown.ts]
2+
type S =
3+
| { type: 'string', value: string }
4+
| { type: 'number', value: number }
5+
| { type: 'unknown', value: unknown }
6+
| { value: undefined };
7+
8+
declare var s: S
9+
10+
if (s.value !== undefined) {
11+
s;
12+
}
13+
else {
14+
s;
15+
}
16+
17+
//// [undefinedAsDiscriminantWithUnknown.js]
18+
if (s.value !== undefined) {
19+
s;
20+
}
21+
else {
22+
s;
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
=== tests/cases/compiler/undefinedAsDiscriminantWithUnknown.ts ===
2+
type S =
3+
>S : Symbol(S, Decl(undefinedAsDiscriminantWithUnknown.ts, 0, 0))
4+
5+
| { type: 'string', value: string }
6+
>type : Symbol(type, Decl(undefinedAsDiscriminantWithUnknown.ts, 1, 3))
7+
>value : Symbol(value, Decl(undefinedAsDiscriminantWithUnknown.ts, 1, 19))
8+
9+
| { type: 'number', value: number }
10+
>type : Symbol(type, Decl(undefinedAsDiscriminantWithUnknown.ts, 2, 3))
11+
>value : Symbol(value, Decl(undefinedAsDiscriminantWithUnknown.ts, 2, 19))
12+
13+
| { type: 'unknown', value: unknown }
14+
>type : Symbol(type, Decl(undefinedAsDiscriminantWithUnknown.ts, 3, 3))
15+
>value : Symbol(value, Decl(undefinedAsDiscriminantWithUnknown.ts, 3, 20))
16+
17+
| { value: undefined };
18+
>value : Symbol(value, Decl(undefinedAsDiscriminantWithUnknown.ts, 4, 3))
19+
20+
declare var s: S
21+
>s : Symbol(s, Decl(undefinedAsDiscriminantWithUnknown.ts, 6, 11))
22+
>S : Symbol(S, Decl(undefinedAsDiscriminantWithUnknown.ts, 0, 0))
23+
24+
if (s.value !== undefined) {
25+
>s.value : Symbol(value, Decl(undefinedAsDiscriminantWithUnknown.ts, 1, 19), Decl(undefinedAsDiscriminantWithUnknown.ts, 2, 19), Decl(undefinedAsDiscriminantWithUnknown.ts, 3, 20), Decl(undefinedAsDiscriminantWithUnknown.ts, 4, 3))
26+
>s : Symbol(s, Decl(undefinedAsDiscriminantWithUnknown.ts, 6, 11))
27+
>value : Symbol(value, Decl(undefinedAsDiscriminantWithUnknown.ts, 1, 19), Decl(undefinedAsDiscriminantWithUnknown.ts, 2, 19), Decl(undefinedAsDiscriminantWithUnknown.ts, 3, 20), Decl(undefinedAsDiscriminantWithUnknown.ts, 4, 3))
28+
>undefined : Symbol(undefined)
29+
30+
s;
31+
>s : Symbol(s, Decl(undefinedAsDiscriminantWithUnknown.ts, 6, 11))
32+
}
33+
else {
34+
s;
35+
>s : Symbol(s, Decl(undefinedAsDiscriminantWithUnknown.ts, 6, 11))
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
=== tests/cases/compiler/undefinedAsDiscriminantWithUnknown.ts ===
2+
type S =
3+
>S : { type: 'string'; value: string; } | { type: 'number'; value: number; } | { type: 'unknown'; value: unknown; } | { value: undefined; }
4+
5+
| { type: 'string', value: string }
6+
>type : "string"
7+
>value : string
8+
9+
| { type: 'number', value: number }
10+
>type : "number"
11+
>value : number
12+
13+
| { type: 'unknown', value: unknown }
14+
>type : "unknown"
15+
>value : unknown
16+
17+
| { value: undefined };
18+
>value : undefined
19+
20+
declare var s: S
21+
>s : S
22+
23+
if (s.value !== undefined) {
24+
>s.value !== undefined : boolean
25+
>s.value : unknown
26+
>s : S
27+
>value : unknown
28+
>undefined : undefined
29+
30+
s;
31+
>s : { type: "string"; value: string; } | { type: "number"; value: number; } | { type: "unknown"; value: unknown; }
32+
}
33+
else {
34+
s;
35+
>s : { type: "unknown"; value: unknown; } | { value: undefined; }
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// @strictNullChecks: true,false
2+
3+
type S =
4+
| { type: 'string', value: string }
5+
| { type: 'number', value: number }
6+
| { type: 'unknown', value: unknown }
7+
| { value: undefined };
8+
9+
declare var s: S
10+
11+
if (s.value !== undefined) {
12+
s;
13+
}
14+
else {
15+
s;
16+
}

0 commit comments

Comments
 (0)