Skip to content

Commit 8202302

Browse files
authored
Fix logic error in ported code (#959)
1 parent f8575fd commit 8202302

File tree

4 files changed

+132
-2
lines changed

4 files changed

+132
-2
lines changed

internal/checker/flow.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -718,8 +718,8 @@ func (c *Checker) narrowTypeByDiscriminant(t *Type, access *ast.Node, narrowType
718718
}
719719
narrowedPropType := narrowType(propType)
720720
return c.filterType(t, func(t *Type) bool {
721-
discriminantType := c.getTypeOfPropertyOrIndexSignatureOfType(t, propName)
722-
return discriminantType == nil || discriminantType.flags&TypeFlagsNever == 0 && narrowedPropType.flags&TypeFlagsNever == 0 && c.areTypesComparable(narrowedPropType, discriminantType)
721+
discriminantType := core.OrElse(c.getTypeOfPropertyOrIndexSignatureOfType(t, propName), c.unknownType)
722+
return discriminantType.flags&TypeFlagsNever == 0 && narrowedPropType.flags&TypeFlagsNever == 0 && c.areTypesComparable(narrowedPropType, discriminantType)
723723
})
724724
}
725725

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
//// [tests/cases/compiler/switchExhaustiveNarrowing.ts] ////
2+
3+
=== switchExhaustiveNarrowing.ts ===
4+
interface ClientSource {
5+
>ClientSource : Symbol(ClientSource, Decl(switchExhaustiveNarrowing.ts, 0, 0))
6+
7+
type: "client";
8+
>type : Symbol(type, Decl(switchExhaustiveNarrowing.ts, 0, 24))
9+
}
10+
11+
interface ServiceSource {
12+
>ServiceSource : Symbol(ServiceSource, Decl(switchExhaustiveNarrowing.ts, 2, 1))
13+
14+
type: "service";
15+
>type : Symbol(type, Decl(switchExhaustiveNarrowing.ts, 4, 25))
16+
}
17+
18+
function isDisplaySource(source: ClientSource | ServiceSource | undefined): boolean {
19+
>isDisplaySource : Symbol(isDisplaySource, Decl(switchExhaustiveNarrowing.ts, 6, 1))
20+
>source : Symbol(source, Decl(switchExhaustiveNarrowing.ts, 8, 25))
21+
>ClientSource : Symbol(ClientSource, Decl(switchExhaustiveNarrowing.ts, 0, 0))
22+
>ServiceSource : Symbol(ServiceSource, Decl(switchExhaustiveNarrowing.ts, 2, 1))
23+
24+
switch (source?.type) {
25+
>source?.type : Symbol(type, Decl(switchExhaustiveNarrowing.ts, 0, 24), Decl(switchExhaustiveNarrowing.ts, 4, 25))
26+
>source : Symbol(source, Decl(switchExhaustiveNarrowing.ts, 8, 25))
27+
>type : Symbol(type, Decl(switchExhaustiveNarrowing.ts, 0, 24), Decl(switchExhaustiveNarrowing.ts, 4, 25))
28+
29+
case "client":
30+
return true;
31+
case "service":
32+
return false;
33+
case undefined:
34+
>undefined : Symbol(undefined)
35+
36+
return false;
37+
default:
38+
neverReached(source);
39+
>neverReached : Symbol(neverReached, Decl(switchExhaustiveNarrowing.ts, 20, 1))
40+
>source : Symbol(source, Decl(switchExhaustiveNarrowing.ts, 8, 25))
41+
42+
return false;
43+
}
44+
}
45+
46+
function neverReached(_v: never): void {}
47+
>neverReached : Symbol(neverReached, Decl(switchExhaustiveNarrowing.ts, 20, 1))
48+
>_v : Symbol(_v, Decl(switchExhaustiveNarrowing.ts, 22, 22))
49+
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
//// [tests/cases/compiler/switchExhaustiveNarrowing.ts] ////
2+
3+
=== switchExhaustiveNarrowing.ts ===
4+
interface ClientSource {
5+
type: "client";
6+
>type : "client"
7+
}
8+
9+
interface ServiceSource {
10+
type: "service";
11+
>type : "service"
12+
}
13+
14+
function isDisplaySource(source: ClientSource | ServiceSource | undefined): boolean {
15+
>isDisplaySource : (source: ClientSource | ServiceSource | undefined) => boolean
16+
>source : ClientSource | ServiceSource | undefined
17+
18+
switch (source?.type) {
19+
>source?.type : "client" | "service" | undefined
20+
>source : ClientSource | ServiceSource | undefined
21+
>type : "client" | "service" | undefined
22+
23+
case "client":
24+
>"client" : "client"
25+
26+
return true;
27+
>true : true
28+
29+
case "service":
30+
>"service" : "service"
31+
32+
return false;
33+
>false : false
34+
35+
case undefined:
36+
>undefined : undefined
37+
38+
return false;
39+
>false : false
40+
41+
default:
42+
neverReached(source);
43+
>neverReached(source) : void
44+
>neverReached : (_v: never) => void
45+
>source : never
46+
47+
return false;
48+
>false : false
49+
}
50+
}
51+
52+
function neverReached(_v: never): void {}
53+
>neverReached : (_v: never) => void
54+
>_v : never
55+
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// @strict: true
2+
// @noEmit: true
3+
4+
interface ClientSource {
5+
type: "client";
6+
}
7+
8+
interface ServiceSource {
9+
type: "service";
10+
}
11+
12+
function isDisplaySource(source: ClientSource | ServiceSource | undefined): boolean {
13+
switch (source?.type) {
14+
case "client":
15+
return true;
16+
case "service":
17+
return false;
18+
case undefined:
19+
return false;
20+
default:
21+
neverReached(source);
22+
return false;
23+
}
24+
}
25+
26+
function neverReached(_v: never): void {}

0 commit comments

Comments
 (0)