Skip to content

Commit 5a8a0bb

Browse files
committed
Add tests
1 parent 771a055 commit 5a8a0bb

File tree

5 files changed

+333
-0
lines changed

5 files changed

+333
-0
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
tests/cases/conformance/types/intersection/intersectionNarrowing.ts(36,16): error TS2367: This condition will always return 'false' since the types 'T & number' and 'string' have no overlap.
2+
3+
4+
==== tests/cases/conformance/types/intersection/intersectionNarrowing.ts (1 errors) ====
5+
// Repros from #43130
6+
7+
function f1<T>(x: T & string | T & undefined) {
8+
if (x) {
9+
x; // Should narrow to T & string
10+
}
11+
}
12+
13+
function f2<T>(x: T & string | T & undefined) {
14+
if (x !== undefined) {
15+
x; // Should narrow to T & string
16+
}
17+
else {
18+
x; // Should narrow to T & undefined
19+
}
20+
}
21+
22+
function f3<T>(x: T & string | T & number) {
23+
if (typeof x === "string") {
24+
x; // Should narrow to T & string
25+
}
26+
else {
27+
x; // Should narrow to T & number
28+
}
29+
}
30+
31+
function f4<T>(x: T & 1 | T & 2) {
32+
switch (x) {
33+
case 1: x; break; // T & 1
34+
case 2: x; break; // T & 2
35+
default: x; // Should narrow to never
36+
}
37+
}
38+
39+
function f5<T extends string | number>(x: T & number) {
40+
const t1 = x === "hello"; // Should be an error
41+
~~~~~~~~~~~~~
42+
!!! error TS2367: This condition will always return 'false' since the types 'T & number' and 'string' have no overlap.
43+
}
44+
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
//// [intersectionNarrowing.ts]
2+
// Repros from #43130
3+
4+
function f1<T>(x: T & string | T & undefined) {
5+
if (x) {
6+
x; // Should narrow to T & string
7+
}
8+
}
9+
10+
function f2<T>(x: T & string | T & undefined) {
11+
if (x !== undefined) {
12+
x; // Should narrow to T & string
13+
}
14+
else {
15+
x; // Should narrow to T & undefined
16+
}
17+
}
18+
19+
function f3<T>(x: T & string | T & number) {
20+
if (typeof x === "string") {
21+
x; // Should narrow to T & string
22+
}
23+
else {
24+
x; // Should narrow to T & number
25+
}
26+
}
27+
28+
function f4<T>(x: T & 1 | T & 2) {
29+
switch (x) {
30+
case 1: x; break; // T & 1
31+
case 2: x; break; // T & 2
32+
default: x; // Should narrow to never
33+
}
34+
}
35+
36+
function f5<T extends string | number>(x: T & number) {
37+
const t1 = x === "hello"; // Should be an error
38+
}
39+
40+
41+
//// [intersectionNarrowing.js]
42+
"use strict";
43+
// Repros from #43130
44+
function f1(x) {
45+
if (x) {
46+
x; // Should narrow to T & string
47+
}
48+
}
49+
function f2(x) {
50+
if (x !== undefined) {
51+
x; // Should narrow to T & string
52+
}
53+
else {
54+
x; // Should narrow to T & undefined
55+
}
56+
}
57+
function f3(x) {
58+
if (typeof x === "string") {
59+
x; // Should narrow to T & string
60+
}
61+
else {
62+
x; // Should narrow to T & number
63+
}
64+
}
65+
function f4(x) {
66+
switch (x) {
67+
case 1:
68+
x;
69+
break; // T & 1
70+
case 2:
71+
x;
72+
break; // T & 2
73+
default: x; // Should narrow to never
74+
}
75+
}
76+
function f5(x) {
77+
var t1 = x === "hello"; // Should be an error
78+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
=== tests/cases/conformance/types/intersection/intersectionNarrowing.ts ===
2+
// Repros from #43130
3+
4+
function f1<T>(x: T & string | T & undefined) {
5+
>f1 : Symbol(f1, Decl(intersectionNarrowing.ts, 0, 0))
6+
>T : Symbol(T, Decl(intersectionNarrowing.ts, 2, 12))
7+
>x : Symbol(x, Decl(intersectionNarrowing.ts, 2, 15))
8+
>T : Symbol(T, Decl(intersectionNarrowing.ts, 2, 12))
9+
>T : Symbol(T, Decl(intersectionNarrowing.ts, 2, 12))
10+
11+
if (x) {
12+
>x : Symbol(x, Decl(intersectionNarrowing.ts, 2, 15))
13+
14+
x; // Should narrow to T & string
15+
>x : Symbol(x, Decl(intersectionNarrowing.ts, 2, 15))
16+
}
17+
}
18+
19+
function f2<T>(x: T & string | T & undefined) {
20+
>f2 : Symbol(f2, Decl(intersectionNarrowing.ts, 6, 1))
21+
>T : Symbol(T, Decl(intersectionNarrowing.ts, 8, 12))
22+
>x : Symbol(x, Decl(intersectionNarrowing.ts, 8, 15))
23+
>T : Symbol(T, Decl(intersectionNarrowing.ts, 8, 12))
24+
>T : Symbol(T, Decl(intersectionNarrowing.ts, 8, 12))
25+
26+
if (x !== undefined) {
27+
>x : Symbol(x, Decl(intersectionNarrowing.ts, 8, 15))
28+
>undefined : Symbol(undefined)
29+
30+
x; // Should narrow to T & string
31+
>x : Symbol(x, Decl(intersectionNarrowing.ts, 8, 15))
32+
}
33+
else {
34+
x; // Should narrow to T & undefined
35+
>x : Symbol(x, Decl(intersectionNarrowing.ts, 8, 15))
36+
}
37+
}
38+
39+
function f3<T>(x: T & string | T & number) {
40+
>f3 : Symbol(f3, Decl(intersectionNarrowing.ts, 15, 1))
41+
>T : Symbol(T, Decl(intersectionNarrowing.ts, 17, 12))
42+
>x : Symbol(x, Decl(intersectionNarrowing.ts, 17, 15))
43+
>T : Symbol(T, Decl(intersectionNarrowing.ts, 17, 12))
44+
>T : Symbol(T, Decl(intersectionNarrowing.ts, 17, 12))
45+
46+
if (typeof x === "string") {
47+
>x : Symbol(x, Decl(intersectionNarrowing.ts, 17, 15))
48+
49+
x; // Should narrow to T & string
50+
>x : Symbol(x, Decl(intersectionNarrowing.ts, 17, 15))
51+
}
52+
else {
53+
x; // Should narrow to T & number
54+
>x : Symbol(x, Decl(intersectionNarrowing.ts, 17, 15))
55+
}
56+
}
57+
58+
function f4<T>(x: T & 1 | T & 2) {
59+
>f4 : Symbol(f4, Decl(intersectionNarrowing.ts, 24, 1))
60+
>T : Symbol(T, Decl(intersectionNarrowing.ts, 26, 12))
61+
>x : Symbol(x, Decl(intersectionNarrowing.ts, 26, 15))
62+
>T : Symbol(T, Decl(intersectionNarrowing.ts, 26, 12))
63+
>T : Symbol(T, Decl(intersectionNarrowing.ts, 26, 12))
64+
65+
switch (x) {
66+
>x : Symbol(x, Decl(intersectionNarrowing.ts, 26, 15))
67+
68+
case 1: x; break; // T & 1
69+
>x : Symbol(x, Decl(intersectionNarrowing.ts, 26, 15))
70+
71+
case 2: x; break; // T & 2
72+
>x : Symbol(x, Decl(intersectionNarrowing.ts, 26, 15))
73+
74+
default: x; // Should narrow to never
75+
>x : Symbol(x, Decl(intersectionNarrowing.ts, 26, 15))
76+
}
77+
}
78+
79+
function f5<T extends string | number>(x: T & number) {
80+
>f5 : Symbol(f5, Decl(intersectionNarrowing.ts, 32, 1))
81+
>T : Symbol(T, Decl(intersectionNarrowing.ts, 34, 12))
82+
>x : Symbol(x, Decl(intersectionNarrowing.ts, 34, 39))
83+
>T : Symbol(T, Decl(intersectionNarrowing.ts, 34, 12))
84+
85+
const t1 = x === "hello"; // Should be an error
86+
>t1 : Symbol(t1, Decl(intersectionNarrowing.ts, 35, 9))
87+
>x : Symbol(x, Decl(intersectionNarrowing.ts, 34, 39))
88+
}
89+
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
=== tests/cases/conformance/types/intersection/intersectionNarrowing.ts ===
2+
// Repros from #43130
3+
4+
function f1<T>(x: T & string | T & undefined) {
5+
>f1 : <T>(x: (T & string) | (T & undefined)) => void
6+
>x : (T & string) | (T & undefined)
7+
8+
if (x) {
9+
>x : (T & string) | (T & undefined)
10+
11+
x; // Should narrow to T & string
12+
>x : T & string
13+
}
14+
}
15+
16+
function f2<T>(x: T & string | T & undefined) {
17+
>f2 : <T>(x: (T & string) | (T & undefined)) => void
18+
>x : (T & string) | (T & undefined)
19+
20+
if (x !== undefined) {
21+
>x !== undefined : boolean
22+
>x : (T & string) | (T & undefined)
23+
>undefined : undefined
24+
25+
x; // Should narrow to T & string
26+
>x : T & string
27+
}
28+
else {
29+
x; // Should narrow to T & undefined
30+
>x : T & undefined
31+
}
32+
}
33+
34+
function f3<T>(x: T & string | T & number) {
35+
>f3 : <T>(x: (T & string) | (T & number)) => void
36+
>x : (T & string) | (T & number)
37+
38+
if (typeof x === "string") {
39+
>typeof x === "string" : boolean
40+
>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
41+
>x : (T & string) | (T & number)
42+
>"string" : "string"
43+
44+
x; // Should narrow to T & string
45+
>x : T & string
46+
}
47+
else {
48+
x; // Should narrow to T & number
49+
>x : T & number
50+
}
51+
}
52+
53+
function f4<T>(x: T & 1 | T & 2) {
54+
>f4 : <T>(x: (T & 1) | (T & 2)) => void
55+
>x : (T & 1) | (T & 2)
56+
57+
switch (x) {
58+
>x : (T & 1) | (T & 2)
59+
60+
case 1: x; break; // T & 1
61+
>1 : 1
62+
>x : T & 1
63+
64+
case 2: x; break; // T & 2
65+
>2 : 2
66+
>x : T & 2
67+
68+
default: x; // Should narrow to never
69+
>x : never
70+
}
71+
}
72+
73+
function f5<T extends string | number>(x: T & number) {
74+
>f5 : <T extends string | number>(x: T & number) => void
75+
>x : T & number
76+
77+
const t1 = x === "hello"; // Should be an error
78+
>t1 : boolean
79+
>x === "hello" : boolean
80+
>x : T & number
81+
>"hello" : "hello"
82+
}
83+
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// @strict: true
2+
3+
// Repros from #43130
4+
5+
function f1<T>(x: T & string | T & undefined) {
6+
if (x) {
7+
x; // Should narrow to T & string
8+
}
9+
}
10+
11+
function f2<T>(x: T & string | T & undefined) {
12+
if (x !== undefined) {
13+
x; // Should narrow to T & string
14+
}
15+
else {
16+
x; // Should narrow to T & undefined
17+
}
18+
}
19+
20+
function f3<T>(x: T & string | T & number) {
21+
if (typeof x === "string") {
22+
x; // Should narrow to T & string
23+
}
24+
else {
25+
x; // Should narrow to T & number
26+
}
27+
}
28+
29+
function f4<T>(x: T & 1 | T & 2) {
30+
switch (x) {
31+
case 1: x; break; // T & 1
32+
case 2: x; break; // T & 2
33+
default: x; // Should narrow to never
34+
}
35+
}
36+
37+
function f5<T extends string | number>(x: T & number) {
38+
const t1 = x === "hello"; // Should be an error
39+
}

0 commit comments

Comments
 (0)