Skip to content

Commit 14985d4

Browse files
committed
Add tests
1 parent d44732a commit 14985d4

File tree

4 files changed

+613
-0
lines changed

4 files changed

+613
-0
lines changed
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
//// [narrowingMutualSubtypes.ts]
2+
// Check that `any` is a strict supertype of `unknown`
3+
4+
declare const ru1: { [x: string]: unknown };
5+
declare const ra1: { [x: string]: any };
6+
7+
const a1a = [ru1, ra1]; // { [x: string]: any }[]
8+
const a1b = [ra1, ru1]; // { [x: string]: any }[]
9+
10+
declare const ra2: { [x: string]: any };
11+
declare const ru2: { [x: string]: unknown };
12+
13+
const a2a = [ru2, ra2]; // { [x: string]: any }[]
14+
const a2b = [ra2, ru2]; // { [x: string]: any }[]
15+
16+
// Check that `{}` is strict supertype of any non-empty object
17+
18+
const c3 = {};
19+
declare const r3: { [x: string]: unknown }
20+
21+
const a3a = [c3, r3]; // {}[]
22+
const a3b = [r3, c3]; // {}[]
23+
24+
declare const r4: { [x: string]: unknown }
25+
const c4 = {};
26+
27+
const a4a = [c4, r4]; // {}[]
28+
const a4b = [r4, c4]; // {}[]
29+
30+
// Check that narrowing preserves original type in false branch for non-identical mutual subtypes
31+
32+
declare function isObject1(value: unknown): value is Record<string, unknown>;
33+
34+
function gg(x: {}) {
35+
if (isObject1(x)) {
36+
x; // Record<string, unknown>
37+
}
38+
else {
39+
x; // {}
40+
}
41+
x; // {}
42+
}
43+
44+
declare function isObject2(value: unknown): value is {};
45+
46+
function gg2(x: Record<string, unknown>) {
47+
if (isObject2(x)) {
48+
x; // {}
49+
}
50+
else {
51+
x; // Record<string, unknown>
52+
}
53+
x; // Record<string, unknown>
54+
}
55+
56+
// Repro from #50916
57+
58+
type Identity<T> = {[K in keyof T]: T[K]};
59+
60+
type Self<T> = T extends unknown ? Identity<T> : never;
61+
62+
function is<T>(value: T): value is Self<T> {
63+
return true;
64+
}
65+
66+
type Union = {a: number} | {b: number} | {c: number};
67+
68+
function example(x: Union) {
69+
if (is(x)) {}
70+
if (is(x)) {}
71+
if (is(x)) {}
72+
if (is(x)) {}
73+
if (is(x)) {}
74+
if (is(x)) {}
75+
if (is(x)) {}
76+
if (is(x)) {}
77+
x; // Union
78+
}
79+
80+
81+
//// [narrowingMutualSubtypes.js]
82+
"use strict";
83+
// Check that `any` is a strict supertype of `unknown`
84+
var a1a = [ru1, ra1]; // { [x: string]: any }[]
85+
var a1b = [ra1, ru1]; // { [x: string]: any }[]
86+
var a2a = [ru2, ra2]; // { [x: string]: any }[]
87+
var a2b = [ra2, ru2]; // { [x: string]: any }[]
88+
// Check that `{}` is strict supertype of any non-empty object
89+
var c3 = {};
90+
var a3a = [c3, r3]; // {}[]
91+
var a3b = [r3, c3]; // {}[]
92+
var c4 = {};
93+
var a4a = [c4, r4]; // {}[]
94+
var a4b = [r4, c4]; // {}[]
95+
function gg(x) {
96+
if (isObject1(x)) {
97+
x; // Record<string, unknown>
98+
}
99+
else {
100+
x; // {}
101+
}
102+
x; // {}
103+
}
104+
function gg2(x) {
105+
if (isObject2(x)) {
106+
x; // {}
107+
}
108+
else {
109+
x; // Record<string, unknown>
110+
}
111+
x; // Record<string, unknown>
112+
}
113+
function is(value) {
114+
return true;
115+
}
116+
function example(x) {
117+
if (is(x)) { }
118+
if (is(x)) { }
119+
if (is(x)) { }
120+
if (is(x)) { }
121+
if (is(x)) { }
122+
if (is(x)) { }
123+
if (is(x)) { }
124+
if (is(x)) { }
125+
x; // Union
126+
}
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
=== tests/cases/compiler/narrowingMutualSubtypes.ts ===
2+
// Check that `any` is a strict supertype of `unknown`
3+
4+
declare const ru1: { [x: string]: unknown };
5+
>ru1 : Symbol(ru1, Decl(narrowingMutualSubtypes.ts, 2, 13))
6+
>x : Symbol(x, Decl(narrowingMutualSubtypes.ts, 2, 22))
7+
8+
declare const ra1: { [x: string]: any };
9+
>ra1 : Symbol(ra1, Decl(narrowingMutualSubtypes.ts, 3, 13))
10+
>x : Symbol(x, Decl(narrowingMutualSubtypes.ts, 3, 22))
11+
12+
const a1a = [ru1, ra1]; // { [x: string]: any }[]
13+
>a1a : Symbol(a1a, Decl(narrowingMutualSubtypes.ts, 5, 5))
14+
>ru1 : Symbol(ru1, Decl(narrowingMutualSubtypes.ts, 2, 13))
15+
>ra1 : Symbol(ra1, Decl(narrowingMutualSubtypes.ts, 3, 13))
16+
17+
const a1b = [ra1, ru1]; // { [x: string]: any }[]
18+
>a1b : Symbol(a1b, Decl(narrowingMutualSubtypes.ts, 6, 5))
19+
>ra1 : Symbol(ra1, Decl(narrowingMutualSubtypes.ts, 3, 13))
20+
>ru1 : Symbol(ru1, Decl(narrowingMutualSubtypes.ts, 2, 13))
21+
22+
declare const ra2: { [x: string]: any };
23+
>ra2 : Symbol(ra2, Decl(narrowingMutualSubtypes.ts, 8, 13))
24+
>x : Symbol(x, Decl(narrowingMutualSubtypes.ts, 8, 22))
25+
26+
declare const ru2: { [x: string]: unknown };
27+
>ru2 : Symbol(ru2, Decl(narrowingMutualSubtypes.ts, 9, 13))
28+
>x : Symbol(x, Decl(narrowingMutualSubtypes.ts, 9, 22))
29+
30+
const a2a = [ru2, ra2]; // { [x: string]: any }[]
31+
>a2a : Symbol(a2a, Decl(narrowingMutualSubtypes.ts, 11, 5))
32+
>ru2 : Symbol(ru2, Decl(narrowingMutualSubtypes.ts, 9, 13))
33+
>ra2 : Symbol(ra2, Decl(narrowingMutualSubtypes.ts, 8, 13))
34+
35+
const a2b = [ra2, ru2]; // { [x: string]: any }[]
36+
>a2b : Symbol(a2b, Decl(narrowingMutualSubtypes.ts, 12, 5))
37+
>ra2 : Symbol(ra2, Decl(narrowingMutualSubtypes.ts, 8, 13))
38+
>ru2 : Symbol(ru2, Decl(narrowingMutualSubtypes.ts, 9, 13))
39+
40+
// Check that `{}` is strict supertype of any non-empty object
41+
42+
const c3 = {};
43+
>c3 : Symbol(c3, Decl(narrowingMutualSubtypes.ts, 16, 5))
44+
45+
declare const r3: { [x: string]: unknown }
46+
>r3 : Symbol(r3, Decl(narrowingMutualSubtypes.ts, 17, 13))
47+
>x : Symbol(x, Decl(narrowingMutualSubtypes.ts, 17, 21))
48+
49+
const a3a = [c3, r3]; // {}[]
50+
>a3a : Symbol(a3a, Decl(narrowingMutualSubtypes.ts, 19, 5))
51+
>c3 : Symbol(c3, Decl(narrowingMutualSubtypes.ts, 16, 5))
52+
>r3 : Symbol(r3, Decl(narrowingMutualSubtypes.ts, 17, 13))
53+
54+
const a3b = [r3, c3]; // {}[]
55+
>a3b : Symbol(a3b, Decl(narrowingMutualSubtypes.ts, 20, 5))
56+
>r3 : Symbol(r3, Decl(narrowingMutualSubtypes.ts, 17, 13))
57+
>c3 : Symbol(c3, Decl(narrowingMutualSubtypes.ts, 16, 5))
58+
59+
declare const r4: { [x: string]: unknown }
60+
>r4 : Symbol(r4, Decl(narrowingMutualSubtypes.ts, 22, 13))
61+
>x : Symbol(x, Decl(narrowingMutualSubtypes.ts, 22, 21))
62+
63+
const c4 = {};
64+
>c4 : Symbol(c4, Decl(narrowingMutualSubtypes.ts, 23, 5))
65+
66+
const a4a = [c4, r4]; // {}[]
67+
>a4a : Symbol(a4a, Decl(narrowingMutualSubtypes.ts, 25, 5))
68+
>c4 : Symbol(c4, Decl(narrowingMutualSubtypes.ts, 23, 5))
69+
>r4 : Symbol(r4, Decl(narrowingMutualSubtypes.ts, 22, 13))
70+
71+
const a4b = [r4, c4]; // {}[]
72+
>a4b : Symbol(a4b, Decl(narrowingMutualSubtypes.ts, 26, 5))
73+
>r4 : Symbol(r4, Decl(narrowingMutualSubtypes.ts, 22, 13))
74+
>c4 : Symbol(c4, Decl(narrowingMutualSubtypes.ts, 23, 5))
75+
76+
// Check that narrowing preserves original type in false branch for non-identical mutual subtypes
77+
78+
declare function isObject1(value: unknown): value is Record<string, unknown>;
79+
>isObject1 : Symbol(isObject1, Decl(narrowingMutualSubtypes.ts, 26, 21))
80+
>value : Symbol(value, Decl(narrowingMutualSubtypes.ts, 30, 27))
81+
>value : Symbol(value, Decl(narrowingMutualSubtypes.ts, 30, 27))
82+
>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
83+
84+
function gg(x: {}) {
85+
>gg : Symbol(gg, Decl(narrowingMutualSubtypes.ts, 30, 77))
86+
>x : Symbol(x, Decl(narrowingMutualSubtypes.ts, 32, 12))
87+
88+
if (isObject1(x)) {
89+
>isObject1 : Symbol(isObject1, Decl(narrowingMutualSubtypes.ts, 26, 21))
90+
>x : Symbol(x, Decl(narrowingMutualSubtypes.ts, 32, 12))
91+
92+
x; // Record<string, unknown>
93+
>x : Symbol(x, Decl(narrowingMutualSubtypes.ts, 32, 12))
94+
}
95+
else {
96+
x; // {}
97+
>x : Symbol(x, Decl(narrowingMutualSubtypes.ts, 32, 12))
98+
}
99+
x; // {}
100+
>x : Symbol(x, Decl(narrowingMutualSubtypes.ts, 32, 12))
101+
}
102+
103+
declare function isObject2(value: unknown): value is {};
104+
>isObject2 : Symbol(isObject2, Decl(narrowingMutualSubtypes.ts, 40, 1))
105+
>value : Symbol(value, Decl(narrowingMutualSubtypes.ts, 42, 27))
106+
>value : Symbol(value, Decl(narrowingMutualSubtypes.ts, 42, 27))
107+
108+
function gg2(x: Record<string, unknown>) {
109+
>gg2 : Symbol(gg2, Decl(narrowingMutualSubtypes.ts, 42, 56))
110+
>x : Symbol(x, Decl(narrowingMutualSubtypes.ts, 44, 13))
111+
>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
112+
113+
if (isObject2(x)) {
114+
>isObject2 : Symbol(isObject2, Decl(narrowingMutualSubtypes.ts, 40, 1))
115+
>x : Symbol(x, Decl(narrowingMutualSubtypes.ts, 44, 13))
116+
117+
x; // {}
118+
>x : Symbol(x, Decl(narrowingMutualSubtypes.ts, 44, 13))
119+
}
120+
else {
121+
x; // Record<string, unknown>
122+
>x : Symbol(x, Decl(narrowingMutualSubtypes.ts, 44, 13))
123+
}
124+
x; // Record<string, unknown>
125+
>x : Symbol(x, Decl(narrowingMutualSubtypes.ts, 44, 13))
126+
}
127+
128+
// Repro from #50916
129+
130+
type Identity<T> = {[K in keyof T]: T[K]};
131+
>Identity : Symbol(Identity, Decl(narrowingMutualSubtypes.ts, 52, 1))
132+
>T : Symbol(T, Decl(narrowingMutualSubtypes.ts, 56, 14))
133+
>K : Symbol(K, Decl(narrowingMutualSubtypes.ts, 56, 21))
134+
>T : Symbol(T, Decl(narrowingMutualSubtypes.ts, 56, 14))
135+
>T : Symbol(T, Decl(narrowingMutualSubtypes.ts, 56, 14))
136+
>K : Symbol(K, Decl(narrowingMutualSubtypes.ts, 56, 21))
137+
138+
type Self<T> = T extends unknown ? Identity<T> : never;
139+
>Self : Symbol(Self, Decl(narrowingMutualSubtypes.ts, 56, 42))
140+
>T : Symbol(T, Decl(narrowingMutualSubtypes.ts, 58, 10))
141+
>T : Symbol(T, Decl(narrowingMutualSubtypes.ts, 58, 10))
142+
>Identity : Symbol(Identity, Decl(narrowingMutualSubtypes.ts, 52, 1))
143+
>T : Symbol(T, Decl(narrowingMutualSubtypes.ts, 58, 10))
144+
145+
function is<T>(value: T): value is Self<T> {
146+
>is : Symbol(is, Decl(narrowingMutualSubtypes.ts, 58, 55))
147+
>T : Symbol(T, Decl(narrowingMutualSubtypes.ts, 60, 12))
148+
>value : Symbol(value, Decl(narrowingMutualSubtypes.ts, 60, 15))
149+
>T : Symbol(T, Decl(narrowingMutualSubtypes.ts, 60, 12))
150+
>value : Symbol(value, Decl(narrowingMutualSubtypes.ts, 60, 15))
151+
>Self : Symbol(Self, Decl(narrowingMutualSubtypes.ts, 56, 42))
152+
>T : Symbol(T, Decl(narrowingMutualSubtypes.ts, 60, 12))
153+
154+
return true;
155+
}
156+
157+
type Union = {a: number} | {b: number} | {c: number};
158+
>Union : Symbol(Union, Decl(narrowingMutualSubtypes.ts, 62, 1))
159+
>a : Symbol(a, Decl(narrowingMutualSubtypes.ts, 64, 15))
160+
>b : Symbol(b, Decl(narrowingMutualSubtypes.ts, 64, 29))
161+
>c : Symbol(c, Decl(narrowingMutualSubtypes.ts, 64, 43))
162+
163+
function example(x: Union) {
164+
>example : Symbol(example, Decl(narrowingMutualSubtypes.ts, 64, 54))
165+
>x : Symbol(x, Decl(narrowingMutualSubtypes.ts, 66, 17))
166+
>Union : Symbol(Union, Decl(narrowingMutualSubtypes.ts, 62, 1))
167+
168+
if (is(x)) {}
169+
>is : Symbol(is, Decl(narrowingMutualSubtypes.ts, 58, 55))
170+
>x : Symbol(x, Decl(narrowingMutualSubtypes.ts, 66, 17))
171+
172+
if (is(x)) {}
173+
>is : Symbol(is, Decl(narrowingMutualSubtypes.ts, 58, 55))
174+
>x : Symbol(x, Decl(narrowingMutualSubtypes.ts, 66, 17))
175+
176+
if (is(x)) {}
177+
>is : Symbol(is, Decl(narrowingMutualSubtypes.ts, 58, 55))
178+
>x : Symbol(x, Decl(narrowingMutualSubtypes.ts, 66, 17))
179+
180+
if (is(x)) {}
181+
>is : Symbol(is, Decl(narrowingMutualSubtypes.ts, 58, 55))
182+
>x : Symbol(x, Decl(narrowingMutualSubtypes.ts, 66, 17))
183+
184+
if (is(x)) {}
185+
>is : Symbol(is, Decl(narrowingMutualSubtypes.ts, 58, 55))
186+
>x : Symbol(x, Decl(narrowingMutualSubtypes.ts, 66, 17))
187+
188+
if (is(x)) {}
189+
>is : Symbol(is, Decl(narrowingMutualSubtypes.ts, 58, 55))
190+
>x : Symbol(x, Decl(narrowingMutualSubtypes.ts, 66, 17))
191+
192+
if (is(x)) {}
193+
>is : Symbol(is, Decl(narrowingMutualSubtypes.ts, 58, 55))
194+
>x : Symbol(x, Decl(narrowingMutualSubtypes.ts, 66, 17))
195+
196+
if (is(x)) {}
197+
>is : Symbol(is, Decl(narrowingMutualSubtypes.ts, 58, 55))
198+
>x : Symbol(x, Decl(narrowingMutualSubtypes.ts, 66, 17))
199+
200+
x; // Union
201+
>x : Symbol(x, Decl(narrowingMutualSubtypes.ts, 66, 17))
202+
}
203+

0 commit comments

Comments
 (0)