-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexample.ts
341 lines (318 loc) · 14.6 KB
/
example.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
export type Equals<A1 extends any, A2 extends any> =
(<A>() => A extends A2 ? 1 : 0) extends <A>() => A extends A1 ? 1 : 0 ? 1 : 0;
declare function check<Type, Expect, Outcome extends 0 | 1>(
debug?: Type,
): Equals<Equals<Type, Expect>, Outcome>;
declare function checks(checks: 1[]): void;
type Extends<A, B> = A extends B ? true : false;
type Pass = 1;
type Fail = 0;
declare function dbg<T>(x?: T): T;
type a = {a: unknown};
type b = {b: unknown};
type c = {c: unknown};
type d = {d: unknown};
type e = {e: unknown};
type f = {f: unknown};
type g = {g: unknown};
type h = {h: unknown};
type T = a | b | c
type T = a | b & c
type T = a & b | c
type T = a & b & c
type T = a & b & c | d
type T = a & b | c & d
type T = a | b & c | d
dbg<a | b & c | d>();
dbg<a & b | c & d>();
dbg<e | a & b | c & d>();
dbg<a & b | c & d | e>();
dbg<a & b | e | b & c | d | f>();
{
type t = any;
checks([
check<Extends<t , t> , true , Pass>() ,
check<Extends<t , any> , true , Pass>() ,
check<Extends<t , unknown> , true , Pass>() ,
check<Extends<t , {}> , boolean , Pass>() ,
check<Extends<t , { x: string }> , boolean , Pass>() ,
check<Extends<t , symbol> , boolean , Pass>() ,
check<Extends<t , null> , boolean , Pass>() ,
check<Extends<t , undefined> , boolean , Pass>() ,
check<Extends<t , void> , boolean , Pass>() ,
check<Extends<t , number> , boolean , Pass>() ,
check<Extends<t , string> , boolean , Pass>() ,
check<Extends<t , boolean> , boolean , Pass>() ,
check<Extends<t , bigint> , boolean , Pass>() ,
check<Extends<t , symbol> , boolean , Pass>() ,
check<Extends<t , object> , boolean , Pass>() ,
check<Extends<t , Object> , boolean , Pass>() ,
check<Extends<t , Function> , boolean , Pass>() ,
check<Extends<t , String> , boolean , Pass>() ,
check<Extends<t , []> , boolean , Pass>() ,
check<Extends<t , [t]> , boolean , Pass>() ,
check<Extends<t , t[]> , boolean , Pass>() ,
check<Extends<t , 1> , boolean , Pass>() ,
check<Extends<t , ""> , boolean , Pass>() ,
check<Extends<t , true> , boolean , Pass>() ,
check<Extends<t , false> , boolean , Pass>() ,
check<Extends<t , never> , boolean , Pass>() ,
]);
}
{
type t = unknown;
checks([
check<Extends<t , t> , true , Pass>() ,
check<Extends<t , any> , true , Pass>() ,
check<Extends<t , unknown> , true , Pass>() ,
check<Extends<t , {}> , false , Pass>() ,
check<Extends<t , { x: string }> , false , Pass>() ,
check<Extends<t , symbol> , false , Pass>() ,
check<Extends<t , null> , false , Pass>() ,
check<Extends<t , undefined> , false , Pass>() ,
check<Extends<t , void> , false , Pass>() ,
check<Extends<t , number> , false , Pass>() ,
check<Extends<t , string> , false , Pass>() ,
check<Extends<t , boolean> , false , Pass>() ,
check<Extends<t , bigint> , false , Pass>() ,
check<Extends<t , symbol> , false , Pass>() ,
check<Extends<t , object> , false , Pass>() ,
check<Extends<t , Object> , false , Pass>() ,
check<Extends<t , Function> , false , Pass>() ,
check<Extends<t , String> , false , Pass>() ,
check<Extends<t , () => void> , false , Pass>() ,
check<Extends<t , []> , false , Pass>() ,
check<Extends<t , [t]> , false , Pass>() ,
check<Extends<t , t[]> , false , Pass>() ,
check<Extends<t , 1> , false , Pass>() ,
check<Extends<t , ""> , false , Pass>() ,
check<Extends<t , true> , false , Pass>() ,
check<Extends<t , false> , false , Pass>() ,
check<Extends<t , never> , false , Pass>() ,
]);
}
{
type t = {};
checks([
check<Extends<t , t> , true , Pass>() ,
check<Extends<t , any> , true , Pass>() ,
check<Extends<t , unknown> , true , Pass>() ,
check<Extends<t , {}> , true , Pass>() ,
check<Extends<t , { x: string }> , false , Pass>() ,
check<Extends<t , symbol> , false , Pass>() ,
check<Extends<t , null> , false , Pass>() ,
check<Extends<t , undefined> , false , Pass>() ,
check<Extends<t , void> , false , Pass>() ,
check<Extends<t , number> , false , Pass>() ,
check<Extends<t , string> , false , Pass>() ,
check<Extends<t , boolean> , false , Pass>() ,
check<Extends<t , bigint> , false , Pass>() ,
check<Extends<t , symbol> , false , Pass>() ,
check<Extends<t , object> , true , Pass>() ,
check<Extends<t , Object> , true , Pass>() ,
check<Extends<t , Function> , false , Pass>() ,
check<Extends<t , String> , false , Pass>() ,
check<Extends<t , () => void> , false , Pass>() ,
check<Extends<t , []> , false , Pass>() ,
check<Extends<t , [t]> , false , Pass>() ,
check<Extends<t , t[]> , false , Pass>() ,
check<Extends<t , 1> , false , Pass>() ,
check<Extends<t , ""> , false , Pass>() ,
check<Extends<t , true> , false , Pass>() ,
check<Extends<t , false> , false , Pass>() ,
check<Extends<t , never> , false , Pass>() ,
]);
}
{
type t = "string";
checks([
check<Extends<t , t> , true , Pass>() ,
check<Extends<t , any> , true , Pass>() ,
check<Extends<t , unknown> , true , Pass>() ,
check<Extends<t , {}> , true , Pass>() ,
check<Extends<t , { x: string }> , false , Pass>() ,
check<Extends<t , symbol> , false , Pass>() ,
check<Extends<t , null> , false , Pass>() ,
check<Extends<t , undefined> , false , Pass>() ,
check<Extends<t , void> , false , Pass>() ,
check<Extends<t , number> , false , Pass>() ,
check<Extends<t , string> , true , Pass>() ,
check<Extends<t , boolean> , false , Pass>() ,
check<Extends<t , bigint> , false , Pass>() ,
check<Extends<t , symbol> , false , Pass>() ,
check<Extends<t , object> , false , Pass>() ,
check<Extends<t , Object> , true , Pass>() ,
check<Extends<t , Function> , false , Pass>() ,
check<Extends<t , String> , true , Pass>() ,
check<Extends<t , () => void> , false , Pass>() ,
check<Extends<t , []> , false , Pass>() ,
check<Extends<t , [t]> , false , Pass>() ,
check<Extends<t , t[]> , false , Pass>() ,
check<Extends<t , 1> , false , Pass>() ,
check<Extends<t , ""> , false , Pass>() ,
check<Extends<t , true> , false , Pass>() ,
check<Extends<t , false> , false , Pass>() ,
check<Extends<t , never> , false , Pass>() ,
]);
}
{
type t = "String";
checks([
check<Extends<t , t> , true , Pass>() ,
check<Extends<t , any> , true , Pass>() ,
check<Extends<t , unknown> , true , Pass>() ,
check<Extends<t , {}> , true , Pass>() ,
check<Extends<t , { x: string }> , false , Pass>() ,
check<Extends<t , symbol> , false , Pass>() ,
check<Extends<t , null> , false , Pass>() ,
check<Extends<t , undefined> , false , Pass>() ,
check<Extends<t , void> , false , Pass>() ,
check<Extends<t , number> , false , Pass>() ,
check<Extends<t , string> , true , Pass>() ,
check<Extends<t , boolean> , false , Pass>() ,
check<Extends<t , bigint> , false , Pass>() ,
check<Extends<t , symbol> , false , Pass>() ,
check<Extends<t , object> , false , Pass>() ,
check<Extends<t , Object> , true , Pass>() ,
check<Extends<t , Function> , false , Pass>() ,
check<Extends<t , String> , true , Pass>() ,
check<Extends<t , () => void> , false , Pass>() ,
check<Extends<t , []> , false , Pass>() ,
check<Extends<t , [t]> , false , Pass>() ,
check<Extends<t , t[]> , false , Pass>() ,
check<Extends<t , 1> , false , Pass>() ,
check<Extends<t , ""> , false , Pass>() ,
check<Extends<t , true> , false , Pass>() ,
check<Extends<t , false> , false , Pass>() ,
check<Extends<t , never> , false , Pass>() ,
]);
}
{
type t = "string";
checks([
check<Extends<t , t> , true , Pass>() ,
check<Extends<t , any> , true , Pass>() ,
check<Extends<t , unknown> , true , Pass>() ,
check<Extends<t , {}> , true , Pass>() ,
check<Extends<t , { x: string }> , false , Pass>() ,
check<Extends<t , symbol> , false , Pass>() ,
check<Extends<t , null> , false , Pass>() ,
check<Extends<t , undefined> , false , Pass>() ,
check<Extends<t , void> , false , Pass>() ,
check<Extends<t , number> , false , Pass>() ,
check<Extends<t , string> , true , Pass>() ,
check<Extends<t , boolean> , false , Pass>() ,
check<Extends<t , bigint> , false , Pass>() ,
check<Extends<t , symbol> , false , Pass>() ,
check<Extends<t , object> , false , Pass>() ,
check<Extends<t , Object> , true , Pass>() ,
check<Extends<t , Function> , false , Pass>() ,
check<Extends<t , String> , true , Pass>() ,
check<Extends<t , () => void> , false , Pass>() ,
check<Extends<t , []> , false , Pass>() ,
check<Extends<t , [t]> , false , Pass>() ,
check<Extends<t , t[]> , false , Pass>() ,
check<Extends<t , 1> , false , Pass>() ,
check<Extends<t , ""> , false , Pass>() ,
check<Extends<t , true> , false , Pass>() ,
check<Extends<t , false> , false , Pass>() ,
check<Extends<t , never> , false , Pass>() ,
]);
}
{
type t = never;
checks([
check<Extends<t , t> , never , Pass>() ,
check<Extends<t , any> , never , Pass>() ,
check<Extends<t , unknown> , never , Pass>() ,
check<Extends<t , {}> , never , Pass>() ,
check<Extends<t , { x: string }> , never , Pass>() ,
check<Extends<t , symbol> , never , Pass>() ,
check<Extends<t , null> , never , Pass>() ,
check<Extends<t , undefined> , never , Pass>() ,
check<Extends<t , void> , never , Pass>() ,
check<Extends<t , number> , never , Pass>() ,
check<Extends<t , string> , never , Pass>() ,
check<Extends<t , boolean> , never , Pass>() ,
check<Extends<t , bigint> , never , Pass>() ,
check<Extends<t , symbol> , never , Pass>() ,
check<Extends<t , object> , never , Pass>() ,
check<Extends<t , Object> , never , Pass>() ,
check<Extends<t , Function> , never , Pass>() ,
check<Extends<t , String> , never , Pass>() ,
check<Extends<t , () => void> , never , Pass>() ,
check<Extends<t , []> , never , Pass>() ,
check<Extends<t , [t]> , never , Pass>() ,
check<Extends<t , t[]> , never , Pass>() ,
check<Extends<t , 1> , never , Pass>() ,
check<Extends<t , ""> , never , Pass>() ,
check<Extends<t , true> , never , Pass>() ,
check<Extends<t , false> , never , Pass>() ,
check<Extends<t , never> , never , Pass>() ,
]);
}
// Primitives do not extend any other primitives
{
checks([
check<Extends<string , string> , true , Pass>() ,
check<Extends<string , number> , false , Pass>() ,
check<Extends<string , boolean> , false , Pass>() ,
check<Extends<string , bigint> , false , Pass>() ,
check<Extends<string , symbol> , false , Pass>() ,
check<Extends<string , object> , false , Pass>() ,
]);
checks([
check<Extends<object , string> , false , Pass>() ,
check<Extends<object , number> , false , Pass>() ,
check<Extends<object , boolean> , false , Pass>() ,
check<Extends<object , bigint> , false , Pass>() ,
check<Extends<object , symbol> , false , Pass>() ,
check<Extends<object , object> , true , Pass>() ,
]);
checks([
check<Extends<number , string> , false , Pass>() ,
check<Extends<number , number> , true , Pass>() ,
check<Extends<number , boolean> , false , Pass>() ,
check<Extends<number , bigint> , false , Pass>() ,
check<Extends<number , symbol> , false , Pass>() ,
check<Extends<number , object> , false , Pass>() ,
]);
checks([
check<Extends<bigint , string> , false , Pass>() ,
check<Extends<bigint , number> , false , Pass>() ,
check<Extends<bigint , boolean> , false , Pass>() ,
check<Extends<bigint , bigint> , true , Pass>() ,
check<Extends<bigint , symbol> , false , Pass>() ,
check<Extends<bigint , object> , false , Pass>() ,
]);
}
{
checks([
check<Extends<number , null | undefined> , false , Pass>() ,
check<Extends<string , null | undefined> , false , Pass>() ,
check<Extends<1 , null | undefined> , false , Pass>() ,
check<Extends<'' , null | undefined> , false , Pass>() ,
]);
}
{
checks([
check<Extends<number , Object> , true , Pass>() ,
check<Extends<string , Object> , true , Pass>() ,
check<Extends<1 , Object> , true , Pass>() ,
check<Extends<{} , Object> , true , Pass>() ,
check<Extends<false , Object> , true , Pass>() ,
check<Extends<void , Object> , false , Pass>() ,
check<Extends<undefined , Object> , false , Pass>() ,
check<Extends<null , Object> , false , Pass>() ,
]);
checks([
check<Extends<number , object> , false , Pass>() ,
check<Extends<string , object> , false , Pass>() ,
check<Extends<1 , object> , false , Pass>() ,
check<Extends<{} , object> , true , Pass>() ,
check<Extends<false , object> , false , Pass>() ,
check<Extends<void , object> , false , Pass>() ,
check<Extends<undefined , object> , false , Pass>() ,
check<Extends<null , object> , false , Pass>() ,
]);
}