@planet-matrix/mobius-model 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/README.md +30 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +22 -4
- package/package.json +3 -3
- package/scripts/build.ts +4 -4
- package/src/basic/README.md +144 -0
- package/src/basic/array.ts +872 -0
- package/src/basic/bigint.ts +114 -0
- package/src/basic/boolean.ts +180 -0
- package/src/basic/enhance.ts +10 -0
- package/src/basic/error.ts +51 -0
- package/src/basic/function.ts +453 -0
- package/src/basic/helper.ts +276 -0
- package/src/basic/index.ts +17 -0
- package/src/basic/is.ts +320 -0
- package/src/basic/number.ts +178 -0
- package/src/basic/object.ts +140 -0
- package/src/basic/promise.ts +464 -0
- package/src/basic/regexp.ts +7 -0
- package/src/basic/stream.ts +140 -0
- package/src/basic/string.ts +308 -0
- package/src/basic/symbol.ts +164 -0
- package/src/basic/temporal.ts +224 -0
- package/src/encoding/README.md +105 -0
- package/src/encoding/base64.ts +98 -0
- package/src/encoding/index.ts +1 -0
- package/src/index.ts +4 -0
- package/src/random/README.md +109 -0
- package/src/random/index.ts +1 -0
- package/src/random/uuid.ts +103 -0
- package/src/type/README.md +330 -0
- package/src/type/array.ts +5 -0
- package/src/type/boolean.ts +471 -0
- package/src/type/class.ts +419 -0
- package/src/type/function.ts +1519 -0
- package/src/type/helper.ts +135 -0
- package/src/type/index.ts +14 -0
- package/src/type/intersection.ts +93 -0
- package/src/type/is.ts +247 -0
- package/src/type/iteration.ts +233 -0
- package/src/type/number.ts +732 -0
- package/src/type/object.ts +788 -0
- package/src/type/path.ts +73 -0
- package/src/type/string.ts +1004 -0
- package/src/type/tuple.ts +2424 -0
- package/src/type/union.ts +108 -0
- package/tests/unit/basic/array.spec.ts +290 -0
- package/tests/unit/basic/bigint.spec.ts +50 -0
- package/tests/unit/basic/boolean.spec.ts +74 -0
- package/tests/unit/basic/error.spec.ts +32 -0
- package/tests/unit/basic/function.spec.ts +175 -0
- package/tests/unit/basic/helper.spec.ts +118 -0
- package/tests/unit/basic/number.spec.ts +74 -0
- package/tests/unit/basic/object.spec.ts +46 -0
- package/tests/unit/basic/promise.spec.ts +232 -0
- package/tests/unit/basic/regexp.spec.ts +11 -0
- package/tests/unit/basic/stream.spec.ts +120 -0
- package/tests/unit/basic/string.spec.ts +74 -0
- package/tests/unit/basic/symbol.spec.ts +72 -0
- package/tests/unit/basic/temporal.spec.ts +78 -0
- package/tests/unit/encoding/base64.spec.ts +40 -0
- package/tests/unit/random/uuid.spec.ts +37 -0
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +0 -1
- package/dist/reactor/index.d.ts +0 -3
- package/dist/reactor/index.d.ts.map +0 -1
- package/dist/reactor/reactor-core/flags.d.ts +0 -99
- package/dist/reactor/reactor-core/flags.d.ts.map +0 -1
- package/dist/reactor/reactor-core/index.d.ts +0 -4
- package/dist/reactor/reactor-core/index.d.ts.map +0 -1
- package/dist/reactor/reactor-core/primitive.d.ts +0 -276
- package/dist/reactor/reactor-core/primitive.d.ts.map +0 -1
- package/dist/reactor/reactor-core/reactive-system.d.ts +0 -241
- package/dist/reactor/reactor-core/reactive-system.d.ts.map +0 -1
- package/dist/reactor/reactor-operators/branch.d.ts +0 -19
- package/dist/reactor/reactor-operators/branch.d.ts.map +0 -1
- package/dist/reactor/reactor-operators/convert.d.ts +0 -30
- package/dist/reactor/reactor-operators/convert.d.ts.map +0 -1
- package/dist/reactor/reactor-operators/create.d.ts +0 -26
- package/dist/reactor/reactor-operators/create.d.ts.map +0 -1
- package/dist/reactor/reactor-operators/filter.d.ts +0 -269
- package/dist/reactor/reactor-operators/filter.d.ts.map +0 -1
- package/dist/reactor/reactor-operators/index.d.ts +0 -8
- package/dist/reactor/reactor-operators/index.d.ts.map +0 -1
- package/dist/reactor/reactor-operators/join.d.ts +0 -48
- package/dist/reactor/reactor-operators/join.d.ts.map +0 -1
- package/dist/reactor/reactor-operators/map.d.ts +0 -165
- package/dist/reactor/reactor-operators/map.d.ts.map +0 -1
- package/dist/reactor/reactor-operators/utility.d.ts +0 -48
- package/dist/reactor/reactor-operators/utility.d.ts.map +0 -1
|
@@ -0,0 +1,2424 @@
|
|
|
1
|
+
|
|
2
|
+
// ============================================================================
|
|
3
|
+
// Helpers
|
|
4
|
+
// ============================================================================
|
|
5
|
+
|
|
6
|
+
type InternalTupleBuildArray<N extends number, Acc extends readonly unknown[] = []> =
|
|
7
|
+
Acc['length'] extends N
|
|
8
|
+
? Acc
|
|
9
|
+
: InternalTupleBuildArray<N, [...Acc, unknown]>
|
|
10
|
+
/**
|
|
11
|
+
* Build a tuple of length N with unknown elements.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```
|
|
15
|
+
* // Expect: [unknown, unknown]
|
|
16
|
+
* type Example1 = TupleLengthN<2>
|
|
17
|
+
* // Expect: []
|
|
18
|
+
* type Example2 = TupleLengthN<0>
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export type TupleLengthN<N extends number> = InternalTupleBuildArray<N>
|
|
22
|
+
|
|
23
|
+
// ============================================================================
|
|
24
|
+
// Primitives
|
|
25
|
+
// ============================================================================
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Get an empty tuple type.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```
|
|
32
|
+
* // Expect: []
|
|
33
|
+
* type Example1 = TupleEmpty
|
|
34
|
+
* // Expect: true
|
|
35
|
+
* type Example2 = TupleIsEmpty<TupleEmpty>
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export type TupleEmpty = []
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Build a single-element tuple.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```
|
|
45
|
+
* // Expect: [number]
|
|
46
|
+
* type Example1 = TupleSingleton<number>
|
|
47
|
+
* // Expect: [string]
|
|
48
|
+
* type Example2 = TupleSingleton<'a'>
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export type TupleSingleton<T> = [T]
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Build a two-element tuple.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```
|
|
58
|
+
* // Expect: [number, string]
|
|
59
|
+
* type Example1 = TuplePair<number, string>
|
|
60
|
+
* // Expect: [boolean, boolean]
|
|
61
|
+
* type Example2 = TuplePair<boolean, boolean>
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
export type TuplePair<T, U> = [T, U]
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Build a three-element tuple.
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```
|
|
71
|
+
* // Expect: [number, string, boolean]
|
|
72
|
+
* type Example1 = TupleTriple<number, string, boolean>
|
|
73
|
+
* // Expect: [1, 2, 3]
|
|
74
|
+
* type Example2 = TupleTriple<1, 2, 3>
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
export type TupleTriple<T, U, V> = [T, U, V]
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Build a four-element tuple.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```
|
|
84
|
+
* // Expect: [number, string, boolean, null]
|
|
85
|
+
* type Example1 = TupleQuad<number, string, boolean, null>
|
|
86
|
+
* // Expect: [1, 2, 3, 4]
|
|
87
|
+
* type Example2 = TupleQuad<1, 2, 3, 4>
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
export type TupleQuad<T, U, V, W> = [T, U, V, W]
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Build a five-element tuple.
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* ```
|
|
97
|
+
* // Expect: [1, 2, 3, 4, 5]
|
|
98
|
+
* type Example1 = TupleQuint<1, 2, 3, 4, 5>
|
|
99
|
+
* // Expect: [string, string, string, string, string]
|
|
100
|
+
* type Example2 = TupleQuint<string, string, string, string, string>
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
export type TupleQuint<T, U, V, W, X> = [T, U, V, W, X]
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Build a tuple of length 2.
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```
|
|
110
|
+
* // Expect: [unknown, unknown]
|
|
111
|
+
* type Example1 = TupleLength2
|
|
112
|
+
* // Expect: 2
|
|
113
|
+
* type Example2 = TupleLength<TupleLength2>
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
export type TupleLength2 = [unknown, unknown]
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Build a tuple of length 3.
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```
|
|
123
|
+
* // Expect: [unknown, unknown, unknown]
|
|
124
|
+
* type Example1 = TupleLength3
|
|
125
|
+
* // Expect: 3
|
|
126
|
+
* type Example2 = TupleLength<TupleLength3>
|
|
127
|
+
* ```
|
|
128
|
+
*/
|
|
129
|
+
export type TupleLength3 = [unknown, unknown, unknown]
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Build a tuple of length 4.
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* ```
|
|
136
|
+
* // Expect: [unknown, unknown, unknown, unknown]
|
|
137
|
+
* type Example1 = TupleLength4
|
|
138
|
+
* // Expect: 4
|
|
139
|
+
* type Example2 = TupleLength<TupleLength4>
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
142
|
+
export type TupleLength4 = [unknown, unknown, unknown, unknown]
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Build a tuple of length 5.
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* ```
|
|
149
|
+
* // Expect: [unknown, unknown, unknown, unknown, unknown]
|
|
150
|
+
* type Example1 = TupleLength5
|
|
151
|
+
* // Expect: 5
|
|
152
|
+
* type Example2 = TupleLength<TupleLength5>
|
|
153
|
+
* ```
|
|
154
|
+
*/
|
|
155
|
+
export type TupleLength5 = [unknown, unknown, unknown, unknown, unknown]
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Build a tuple of length 6.
|
|
159
|
+
*
|
|
160
|
+
* @example
|
|
161
|
+
* ```
|
|
162
|
+
* // Expect: [unknown, unknown, unknown, unknown, unknown, unknown]
|
|
163
|
+
* type Example1 = TupleLength6
|
|
164
|
+
* // Expect: 6
|
|
165
|
+
* type Example2 = TupleLength<TupleLength6>
|
|
166
|
+
* ```
|
|
167
|
+
*/
|
|
168
|
+
export type TupleLength6 = [unknown, unknown, unknown, unknown, unknown, unknown]
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Build a tuple of length 7.
|
|
172
|
+
*
|
|
173
|
+
* @example
|
|
174
|
+
* ```
|
|
175
|
+
* // Expect: [unknown, unknown, unknown, unknown, unknown, unknown, unknown]
|
|
176
|
+
* type Example1 = TupleLength7
|
|
177
|
+
* // Expect: 7
|
|
178
|
+
* type Example2 = TupleLength<TupleLength7>
|
|
179
|
+
* ```
|
|
180
|
+
*/
|
|
181
|
+
export type TupleLength7 = [unknown, unknown, unknown, unknown, unknown, unknown, unknown]
|
|
182
|
+
|
|
183
|
+
// ============================================================================
|
|
184
|
+
// Validation
|
|
185
|
+
// ============================================================================
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Check if a type is a tuple (not a generic array).
|
|
189
|
+
*
|
|
190
|
+
* @example
|
|
191
|
+
* ```
|
|
192
|
+
* // Expect: true
|
|
193
|
+
* type Example1 = TupleIsTuple<[number, string]>
|
|
194
|
+
* // Expect: false
|
|
195
|
+
* type Example2 = TupleIsTuple<string[]>
|
|
196
|
+
* ```
|
|
197
|
+
*/
|
|
198
|
+
export type TupleIsTuple<T extends readonly unknown[]> = number extends T['length'] ? false : true
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Check if a tuple is empty.
|
|
202
|
+
*
|
|
203
|
+
* @example
|
|
204
|
+
* ```
|
|
205
|
+
* // Expect: true
|
|
206
|
+
* type Example1 = TupleIsEmpty<[]>
|
|
207
|
+
* // Expect: false
|
|
208
|
+
* type Example2 = TupleIsEmpty<[number]>
|
|
209
|
+
* ```
|
|
210
|
+
*/
|
|
211
|
+
export type TupleIsEmpty<T extends readonly unknown[]> = T extends [] ? true : false
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Check if a tuple is non-empty.
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
217
|
+
* ```
|
|
218
|
+
* // Expect: true
|
|
219
|
+
* type Example1 = TupleIsNonEmpty<[number]>
|
|
220
|
+
* // Expect: false
|
|
221
|
+
* type Example2 = TupleIsNonEmpty<[]>
|
|
222
|
+
* ```
|
|
223
|
+
*/
|
|
224
|
+
export type TupleIsNonEmpty<T extends readonly unknown[]> = T extends [] ? false : true
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Check if a tuple is readonly.
|
|
228
|
+
*
|
|
229
|
+
* @example
|
|
230
|
+
* ```
|
|
231
|
+
* // Expect: true
|
|
232
|
+
* type Example1 = TupleIsReadonly<readonly [number]>
|
|
233
|
+
* // Expect: false
|
|
234
|
+
* type Example2 = TupleIsReadonly<[number]>
|
|
235
|
+
* ```
|
|
236
|
+
*/
|
|
237
|
+
export type TupleIsReadonly<T extends readonly unknown[]> = T extends unknown[] ? false : true
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Check if a tuple has fixed length.
|
|
241
|
+
*
|
|
242
|
+
* @example
|
|
243
|
+
* ```
|
|
244
|
+
* // Expect: true
|
|
245
|
+
* type Example1 = TupleIsFixedLength<[number, string]>
|
|
246
|
+
* // Expect: false
|
|
247
|
+
* type Example2 = TupleIsFixedLength<number[]>
|
|
248
|
+
* ```
|
|
249
|
+
*/
|
|
250
|
+
export type TupleIsFixedLength<T extends readonly unknown[]> = TupleIsTuple<T>
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Check if a tuple type is never.
|
|
254
|
+
*
|
|
255
|
+
* @example
|
|
256
|
+
* ```
|
|
257
|
+
* // Expect: true
|
|
258
|
+
* type Example1 = TupleIsNever<never>
|
|
259
|
+
* // Expect: false
|
|
260
|
+
* type Example2 = TupleIsNever<[]>
|
|
261
|
+
* ```
|
|
262
|
+
*/
|
|
263
|
+
export type TupleIsNever<T> = [T] extends [never] ? true : false
|
|
264
|
+
|
|
265
|
+
type InternalIsAny<T> = 0 extends (1 & T) ? true : false
|
|
266
|
+
/**
|
|
267
|
+
* Check if a tuple type is any.
|
|
268
|
+
*
|
|
269
|
+
* @example
|
|
270
|
+
* ```
|
|
271
|
+
* // Expect: true
|
|
272
|
+
* type Example1 = TupleIsAny<any>
|
|
273
|
+
* // Expect: false
|
|
274
|
+
* type Example2 = TupleIsAny<[]>
|
|
275
|
+
* ```
|
|
276
|
+
*/
|
|
277
|
+
export type TupleIsAny<T> = InternalIsAny<T>
|
|
278
|
+
|
|
279
|
+
type InternalIsUnknown<T> =
|
|
280
|
+
InternalIsAny<T> extends true
|
|
281
|
+
? false
|
|
282
|
+
: (unknown extends T ? (T extends unknown ? true : false) : false)
|
|
283
|
+
/**
|
|
284
|
+
* Check if a tuple type is unknown.
|
|
285
|
+
*
|
|
286
|
+
* @example
|
|
287
|
+
* ```
|
|
288
|
+
* // Expect: true
|
|
289
|
+
* type Example1 = TupleIsUnknown<unknown>
|
|
290
|
+
* // Expect: false
|
|
291
|
+
* type Example2 = TupleIsUnknown<[]>
|
|
292
|
+
* ```
|
|
293
|
+
*/
|
|
294
|
+
export type TupleIsUnknown<T> = InternalIsUnknown<T>
|
|
295
|
+
|
|
296
|
+
type InternalIsUnion<T, U = T> = T extends unknown ? ([U] extends [T] ? false : true) : false
|
|
297
|
+
/**
|
|
298
|
+
* Check if a tuple type is a union.
|
|
299
|
+
*
|
|
300
|
+
* @example
|
|
301
|
+
* ```
|
|
302
|
+
* // Expect: true
|
|
303
|
+
* type Example1 = TupleIsUnion<[number] | [string]>
|
|
304
|
+
* // Expect: false
|
|
305
|
+
* type Example2 = TupleIsUnion<[number]>
|
|
306
|
+
* ```
|
|
307
|
+
*/
|
|
308
|
+
export type TupleIsUnion<T> = InternalIsUnion<T>
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Check if a type is array-like.
|
|
312
|
+
*
|
|
313
|
+
* @example
|
|
314
|
+
* ```
|
|
315
|
+
* // Expect: true
|
|
316
|
+
* type Example1 = TupleIsArrayLike<[number]>
|
|
317
|
+
* // Expect: false
|
|
318
|
+
* type Example2 = TupleIsArrayLike<number>
|
|
319
|
+
* ```
|
|
320
|
+
*/
|
|
321
|
+
export type TupleIsArrayLike<T> = T extends readonly unknown[] ? true : false
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Check if a tuple contains a never element.
|
|
325
|
+
*
|
|
326
|
+
* @example
|
|
327
|
+
* ```
|
|
328
|
+
* // Expect: true
|
|
329
|
+
* type Example1 = TupleHasNeverElement<[never, number]>
|
|
330
|
+
* // Expect: false
|
|
331
|
+
* type Example2 = TupleHasNeverElement<[number, string]>
|
|
332
|
+
* ```
|
|
333
|
+
*/
|
|
334
|
+
export type TupleHasNeverElement<T extends readonly unknown[]> =
|
|
335
|
+
T extends readonly [infer First, ...infer Rest]
|
|
336
|
+
? ([First] extends [never] ? true : TupleHasNeverElement<Rest>)
|
|
337
|
+
: false
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Check if all tuple elements are optional (include undefined).
|
|
341
|
+
*
|
|
342
|
+
* @example
|
|
343
|
+
* ```
|
|
344
|
+
* // Expect: true
|
|
345
|
+
* type Example1 = TupleIsAllUndefinedable<[number | undefined, string | undefined]>
|
|
346
|
+
* // Expect: false
|
|
347
|
+
* type Example2 = TupleIsAllUndefinedable<[number, string | undefined]>
|
|
348
|
+
* ```
|
|
349
|
+
*/
|
|
350
|
+
export type TupleIsAllUndefinedable<T extends readonly unknown[]> =
|
|
351
|
+
T extends readonly [infer First, ...infer Rest]
|
|
352
|
+
? (undefined extends First ? TupleIsAllUndefinedable<Rest> : false)
|
|
353
|
+
: true
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Check if all tuple elements are required (exclude undefined).
|
|
357
|
+
*
|
|
358
|
+
* @example
|
|
359
|
+
* ```
|
|
360
|
+
* // Expect: true
|
|
361
|
+
* type Example1 = TupleIsAllNonUndefinedable<[number, string]>
|
|
362
|
+
* // Expect: false
|
|
363
|
+
* type Example2 = TupleIsAllNonUndefinedable<[number | undefined, string]>
|
|
364
|
+
* ```
|
|
365
|
+
*/
|
|
366
|
+
export type TupleIsAllNonUndefinedable<T extends readonly unknown[]> =
|
|
367
|
+
T extends readonly [infer First, ...infer Rest]
|
|
368
|
+
? (undefined extends First ? false : TupleIsAllNonUndefinedable<Rest>)
|
|
369
|
+
: true
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Check if all tuple elements are the same type.
|
|
373
|
+
*
|
|
374
|
+
* @example
|
|
375
|
+
* ```
|
|
376
|
+
* // Expect: true
|
|
377
|
+
* type Example1 = TupleIsHomogeneous<[number, number, number]>
|
|
378
|
+
* // Expect: false
|
|
379
|
+
* type Example2 = TupleIsHomogeneous<[number, string]>
|
|
380
|
+
* ```
|
|
381
|
+
*/
|
|
382
|
+
export type TupleIsHomogeneous<T extends readonly unknown[]> =
|
|
383
|
+
T extends readonly [infer First, ...infer Rest]
|
|
384
|
+
? TupleIsEqual<Rest, InternalTupleRepeat<First, Rest['length']>>
|
|
385
|
+
: true
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* Check if all tuple elements are distinct.
|
|
389
|
+
*
|
|
390
|
+
* @example
|
|
391
|
+
* ```
|
|
392
|
+
* // Expect: true
|
|
393
|
+
* type Example1 = TupleIsDistinct<[1, 2, 3]>
|
|
394
|
+
* // Expect: false
|
|
395
|
+
* type Example2 = TupleIsDistinct<[1, 2, 1]>
|
|
396
|
+
* ```
|
|
397
|
+
*/
|
|
398
|
+
export type TupleIsDistinct<T extends readonly unknown[]> =
|
|
399
|
+
T extends readonly [infer First, ...infer Rest]
|
|
400
|
+
? (TupleIncludes<Rest, First> extends true ? false : TupleIsDistinct<Rest>)
|
|
401
|
+
: true
|
|
402
|
+
|
|
403
|
+
// ============================================================================
|
|
404
|
+
// Comparison
|
|
405
|
+
// ============================================================================
|
|
406
|
+
|
|
407
|
+
type InternalIsEqual<A, B> =
|
|
408
|
+
(<T>() => T extends A ? 1 : 2) extends (<T>() => T extends B ? 1 : 2)
|
|
409
|
+
? true
|
|
410
|
+
: false
|
|
411
|
+
/**
|
|
412
|
+
* Check if two tuples are element-wise equal.
|
|
413
|
+
*
|
|
414
|
+
* @example
|
|
415
|
+
* ```
|
|
416
|
+
* // Expect: true
|
|
417
|
+
* type Example1 = TupleIsEqual<[1, 2], [1, 2]>
|
|
418
|
+
* // Expect: false
|
|
419
|
+
* type Example2 = TupleIsEqual<[1, 2], [2, 1]>
|
|
420
|
+
* ```
|
|
421
|
+
*/
|
|
422
|
+
export type TupleIsEqual<A extends readonly unknown[], B extends readonly unknown[]> =
|
|
423
|
+
A extends readonly [infer FirstA, ...infer RestA]
|
|
424
|
+
? (B extends readonly [infer FirstB, ...infer RestB]
|
|
425
|
+
? (InternalIsEqual<FirstA, FirstB> extends true
|
|
426
|
+
? TupleIsEqual<RestA, RestB>
|
|
427
|
+
: false)
|
|
428
|
+
: false)
|
|
429
|
+
: (B extends [] ? true : false)
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* Check if a tuple starts with a prefix tuple.
|
|
433
|
+
*
|
|
434
|
+
* @example
|
|
435
|
+
* ```
|
|
436
|
+
* // Expect: true
|
|
437
|
+
* type Example1 = TupleStartsWith<[1, 2, 3], [1, 2]>
|
|
438
|
+
* // Expect: false
|
|
439
|
+
* type Example2 = TupleStartsWith<[1, 2, 3], [2, 3]>
|
|
440
|
+
* ```
|
|
441
|
+
*/
|
|
442
|
+
export type TupleStartsWith<T extends readonly unknown[], P extends readonly unknown[]> =
|
|
443
|
+
P extends []
|
|
444
|
+
? true
|
|
445
|
+
: (T extends readonly [infer FirstT, ...infer RestT]
|
|
446
|
+
? (P extends readonly [infer FirstP, ...infer RestP]
|
|
447
|
+
? (InternalIsEqual<FirstT, FirstP> extends true
|
|
448
|
+
? TupleStartsWith<RestT, RestP>
|
|
449
|
+
: false)
|
|
450
|
+
: false)
|
|
451
|
+
: false)
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* Check if a tuple ends with a suffix tuple.
|
|
455
|
+
*
|
|
456
|
+
* @example
|
|
457
|
+
* ```
|
|
458
|
+
* // Expect: true
|
|
459
|
+
* type Example1 = TupleEndsWith<[1, 2, 3], [2, 3]>
|
|
460
|
+
* // Expect: false
|
|
461
|
+
* type Example2 = TupleEndsWith<[1, 2, 3], [1, 3]>
|
|
462
|
+
* ```
|
|
463
|
+
*/
|
|
464
|
+
export type TupleEndsWith<T extends readonly unknown[], S extends readonly unknown[]> =
|
|
465
|
+
TupleStartsWith<TupleReverse<T>, TupleReverse<S>>
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* Check if a tuple includes a value.
|
|
469
|
+
*
|
|
470
|
+
* @example
|
|
471
|
+
* ```
|
|
472
|
+
* // Expect: true
|
|
473
|
+
* type Example1 = TupleIncludes<[1, 2, 3], 2>
|
|
474
|
+
* // Expect: false
|
|
475
|
+
* type Example2 = TupleIncludes<[1, 2, 3], 4>
|
|
476
|
+
* ```
|
|
477
|
+
*/
|
|
478
|
+
export type TupleIncludes<T extends readonly unknown[], U> =
|
|
479
|
+
T extends readonly [infer First, ...infer Rest]
|
|
480
|
+
? (InternalIsEqual<First, U> extends true ? true : TupleIncludes<Rest, U>)
|
|
481
|
+
: false
|
|
482
|
+
|
|
483
|
+
type InternalTupleCompareHelper<A extends number, B extends number> =
|
|
484
|
+
InternalTupleBuildArray<A> extends InternalTupleBuildArray<B>
|
|
485
|
+
? 0
|
|
486
|
+
: (InternalTupleBuildArray<A> extends [...InternalTupleBuildArray<B>, ...infer _]
|
|
487
|
+
? 1
|
|
488
|
+
: -1)
|
|
489
|
+
/**
|
|
490
|
+
* Check if two tuples have the same length.
|
|
491
|
+
*
|
|
492
|
+
* @example
|
|
493
|
+
* ```
|
|
494
|
+
* // Expect: true
|
|
495
|
+
* type Example1 = TupleSameLength<[1, 2], ['a', 'b']>
|
|
496
|
+
* // Expect: false
|
|
497
|
+
* type Example2 = TupleSameLength<[1], ['a', 'b']>
|
|
498
|
+
* ```
|
|
499
|
+
*/
|
|
500
|
+
export type TupleSameLength<A extends readonly unknown[], B extends readonly unknown[]> =
|
|
501
|
+
InternalTupleCompareHelper<A['length'], B['length']> extends 0 ? true : false
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* Alias of TupleStartsWith.
|
|
505
|
+
*
|
|
506
|
+
* @example
|
|
507
|
+
* ```
|
|
508
|
+
* // Expect: true
|
|
509
|
+
* type Example1 = TupleIsPrefix<[1, 2, 3], [1, 2]>
|
|
510
|
+
* // Expect: false
|
|
511
|
+
* type Example2 = TupleIsPrefix<[1, 2, 3], [2, 3]>
|
|
512
|
+
* ```
|
|
513
|
+
*/
|
|
514
|
+
export type TupleIsPrefix<T extends readonly unknown[], P extends readonly unknown[]> = TupleStartsWith<T, P>
|
|
515
|
+
|
|
516
|
+
/**
|
|
517
|
+
* Alias of TupleEndsWith.
|
|
518
|
+
*
|
|
519
|
+
* @example
|
|
520
|
+
* ```
|
|
521
|
+
* // Expect: true
|
|
522
|
+
* type Example1 = TupleIsSuffix<[1, 2, 3], [2, 3]>
|
|
523
|
+
* // Expect: false
|
|
524
|
+
* type Example2 = TupleIsSuffix<[1, 2, 3], [1, 3]>
|
|
525
|
+
* ```
|
|
526
|
+
*/
|
|
527
|
+
export type TupleIsSuffix<T extends readonly unknown[], S extends readonly unknown[]> = TupleEndsWith<T, S>
|
|
528
|
+
|
|
529
|
+
/**
|
|
530
|
+
* Check if every element in A is included in B.
|
|
531
|
+
*
|
|
532
|
+
* @example
|
|
533
|
+
* ```
|
|
534
|
+
* // Expect: true
|
|
535
|
+
* type Example1 = TupleIsSubset<[1, 2], [1, 2, 3]>
|
|
536
|
+
* // Expect: false
|
|
537
|
+
* type Example2 = TupleIsSubset<[1, 4], [1, 2, 3]>
|
|
538
|
+
* ```
|
|
539
|
+
*/
|
|
540
|
+
export type TupleIsSubset<A extends readonly unknown[], B extends readonly unknown[]> =
|
|
541
|
+
A extends readonly [infer First, ...infer Rest]
|
|
542
|
+
? (TupleIncludes<B, First> extends true ? TupleIsSubset<Rest, B> : false)
|
|
543
|
+
: true
|
|
544
|
+
|
|
545
|
+
/**
|
|
546
|
+
* Check if every element in B is included in A.
|
|
547
|
+
*
|
|
548
|
+
* @example
|
|
549
|
+
* ```
|
|
550
|
+
* // Expect: true
|
|
551
|
+
* type Example1 = TupleIsSuperset<[1, 2, 3], [1, 2]>
|
|
552
|
+
* // Expect: false
|
|
553
|
+
* type Example2 = TupleIsSuperset<[1, 2], [1, 3]>
|
|
554
|
+
* ```
|
|
555
|
+
*/
|
|
556
|
+
export type TupleIsSuperset<A extends readonly unknown[], B extends readonly unknown[]> = TupleIsSubset<B, A>
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* Compare tuple lengths and return -1, 0, or 1.
|
|
560
|
+
*
|
|
561
|
+
* @example
|
|
562
|
+
* ```
|
|
563
|
+
* // Expect: 0
|
|
564
|
+
* type Example1 = TupleCompareLength<[1, 2], ['a', 'b']>
|
|
565
|
+
* // Expect: -1
|
|
566
|
+
* type Example2 = TupleCompareLength<[1], ['a', 'b']>
|
|
567
|
+
* ```
|
|
568
|
+
*/
|
|
569
|
+
export type TupleCompareLength<A extends readonly unknown[], B extends readonly unknown[]> =
|
|
570
|
+
InternalTupleCompareHelper<A['length'], B['length']>
|
|
571
|
+
|
|
572
|
+
/**
|
|
573
|
+
* Check if two tuple types are strictly equal.
|
|
574
|
+
*
|
|
575
|
+
* @example
|
|
576
|
+
* ```
|
|
577
|
+
* // Expect: true
|
|
578
|
+
* type Example1 = TupleIsStrictEqual<[1, 2], [1, 2]>
|
|
579
|
+
* // Expect: false
|
|
580
|
+
* type Example2 = TupleIsStrictEqual<[1, 2], [2, 1]>
|
|
581
|
+
* ```
|
|
582
|
+
*/
|
|
583
|
+
export type TupleIsStrictEqual<A, B> = InternalIsEqual<A, B>
|
|
584
|
+
|
|
585
|
+
/**
|
|
586
|
+
* Deeply compare two tuples, recursing into nested tuples.
|
|
587
|
+
*
|
|
588
|
+
* @example
|
|
589
|
+
* ```
|
|
590
|
+
* // Expect: true
|
|
591
|
+
* type Example1 = TupleIsEqualDeep<[[1], [2]], [[1], [2]]>
|
|
592
|
+
* // Expect: false
|
|
593
|
+
* type Example2 = TupleIsEqualDeep<[[1], [2]], [[2], [1]]>
|
|
594
|
+
* ```
|
|
595
|
+
*/
|
|
596
|
+
export type TupleIsEqualDeep<A extends readonly unknown[], B extends readonly unknown[]> =
|
|
597
|
+
A extends readonly [infer FirstA, ...infer RestA]
|
|
598
|
+
? (B extends readonly [infer FirstB, ...infer RestB]
|
|
599
|
+
? (FirstA extends readonly unknown[]
|
|
600
|
+
? (FirstB extends readonly unknown[]
|
|
601
|
+
? (TupleIsEqualDeep<FirstA, FirstB> extends true
|
|
602
|
+
? TupleIsEqualDeep<RestA, RestB>
|
|
603
|
+
: false)
|
|
604
|
+
: false)
|
|
605
|
+
: (InternalIsEqual<FirstA, FirstB> extends true
|
|
606
|
+
? TupleIsEqualDeep<RestA, RestB>
|
|
607
|
+
: false))
|
|
608
|
+
: false)
|
|
609
|
+
: (B extends [] ? true : false)
|
|
610
|
+
|
|
611
|
+
/**
|
|
612
|
+
* Compare tuples lexicographically, returning -1, 0, or 1.
|
|
613
|
+
*
|
|
614
|
+
* @example
|
|
615
|
+
* ```
|
|
616
|
+
* // Expect: 0
|
|
617
|
+
* type Example1 = TupleCompareLexicographic<[1, 2], [1, 2]>
|
|
618
|
+
* // Expect: -1 | 1
|
|
619
|
+
* type Example2 = TupleCompareLexicographic<[1, 2], [1, 3]>
|
|
620
|
+
* ```
|
|
621
|
+
*/
|
|
622
|
+
export type TupleCompareLexicographic<A extends readonly unknown[], B extends readonly unknown[]> =
|
|
623
|
+
A extends readonly [infer FirstA, ...infer RestA]
|
|
624
|
+
? (B extends readonly [infer FirstB, ...infer RestB]
|
|
625
|
+
? (InternalIsEqual<FirstA, FirstB> extends true
|
|
626
|
+
? TupleCompareLexicographic<RestA, RestB>
|
|
627
|
+
: -1 | 1)
|
|
628
|
+
: 1)
|
|
629
|
+
: (B extends [] ? 0 : -1)
|
|
630
|
+
|
|
631
|
+
/**
|
|
632
|
+
* Check if two tuples are equal ignoring element order.
|
|
633
|
+
*
|
|
634
|
+
* @example
|
|
635
|
+
* ```
|
|
636
|
+
* // Expect: true
|
|
637
|
+
* type Example1 = TupleEqualsIgnoringOrder<[1, 2], [2, 1]>
|
|
638
|
+
* // Expect: false
|
|
639
|
+
* type Example2 = TupleEqualsIgnoringOrder<[1, 2], [1, 2, 3]>
|
|
640
|
+
* ```
|
|
641
|
+
*/
|
|
642
|
+
export type TupleEqualsIgnoringOrder<A extends readonly unknown[], B extends readonly unknown[]> =
|
|
643
|
+
TupleSameLength<A, B> extends true
|
|
644
|
+
? (TupleIsSubset<TupleUnique<A>, TupleUnique<B>> extends true
|
|
645
|
+
? TupleIsSubset<TupleUnique<B>, TupleUnique<A>>
|
|
646
|
+
: false)
|
|
647
|
+
: false
|
|
648
|
+
|
|
649
|
+
/**
|
|
650
|
+
* Alias of TupleIsSuperset.
|
|
651
|
+
*
|
|
652
|
+
* @example
|
|
653
|
+
* ```
|
|
654
|
+
* // Expect: true
|
|
655
|
+
* type Example1 = TupleContainsAll<[1, 2, 3], [1, 2]>
|
|
656
|
+
* // Expect: false
|
|
657
|
+
* type Example2 = TupleContainsAll<[1, 2], [1, 3]>
|
|
658
|
+
* ```
|
|
659
|
+
*/
|
|
660
|
+
export type TupleContainsAll<A extends readonly unknown[], B extends readonly unknown[]> = TupleIsSuperset<A, B>
|
|
661
|
+
|
|
662
|
+
// ============================================================================
|
|
663
|
+
// Query
|
|
664
|
+
// ============================================================================
|
|
665
|
+
|
|
666
|
+
type InternalTupleIndexCounter<T extends readonly unknown[], U, Count extends readonly unknown[] = []> =
|
|
667
|
+
T extends readonly [infer First, ...infer Rest]
|
|
668
|
+
? (InternalIsEqual<First, U> extends true
|
|
669
|
+
? Count['length']
|
|
670
|
+
: InternalTupleIndexCounter<Rest, U, [...Count, unknown]>)
|
|
671
|
+
: -1
|
|
672
|
+
/**
|
|
673
|
+
* Get the length of a tuple.
|
|
674
|
+
*
|
|
675
|
+
* @example
|
|
676
|
+
* ```
|
|
677
|
+
* // Expect: 3
|
|
678
|
+
* type Example1 = TupleLength<[1, 2, 3]>
|
|
679
|
+
* // Expect: 0
|
|
680
|
+
* type Example2 = TupleLength<[]>
|
|
681
|
+
* ```
|
|
682
|
+
*/
|
|
683
|
+
export type TupleLength<T extends readonly unknown[]> = T['length']
|
|
684
|
+
|
|
685
|
+
/**
|
|
686
|
+
* Get the first index of a value in a tuple.
|
|
687
|
+
*
|
|
688
|
+
* @example
|
|
689
|
+
* ```
|
|
690
|
+
* // Expect: 1
|
|
691
|
+
* type Example1 = TupleIndexOf<[1, 2, 3], 2>
|
|
692
|
+
* // Expect: -1
|
|
693
|
+
* type Example2 = TupleIndexOf<[1, 2, 3], 4>
|
|
694
|
+
* ```
|
|
695
|
+
*/
|
|
696
|
+
export type TupleIndexOf<T extends readonly unknown[], U> = InternalTupleIndexCounter<T, U>
|
|
697
|
+
|
|
698
|
+
type InternalTupleLastIndexCounter<T extends readonly unknown[], U, Count extends readonly unknown[] = [], Last extends number = -1> =
|
|
699
|
+
T extends readonly [infer First, ...infer Rest]
|
|
700
|
+
? InternalTupleLastIndexCounter<Rest, U, [...Count, unknown], InternalIsEqual<First, U> extends true ? Count['length'] : Last>
|
|
701
|
+
: Last
|
|
702
|
+
/**
|
|
703
|
+
* Get the last index of a value in a tuple.
|
|
704
|
+
*
|
|
705
|
+
* @example
|
|
706
|
+
* ```
|
|
707
|
+
* // Expect: 2
|
|
708
|
+
* type Example1 = TupleLastIndexOf<[1, 2, 1], 1>
|
|
709
|
+
* // Expect: -1
|
|
710
|
+
* type Example2 = TupleLastIndexOf<[1, 2, 3], 4>
|
|
711
|
+
* ```
|
|
712
|
+
*/
|
|
713
|
+
export type TupleLastIndexOf<T extends readonly unknown[], U> = InternalTupleLastIndexCounter<T, U>
|
|
714
|
+
|
|
715
|
+
/**
|
|
716
|
+
* Count occurrences of a value in a tuple.
|
|
717
|
+
*
|
|
718
|
+
* @example
|
|
719
|
+
* ```
|
|
720
|
+
* // Expect: 2
|
|
721
|
+
* type Example1 = TupleCount<[1, 2, 1], 1>
|
|
722
|
+
* // Expect: 0
|
|
723
|
+
* type Example2 = TupleCount<[1, 2, 3], 4>
|
|
724
|
+
* ```
|
|
725
|
+
*/
|
|
726
|
+
export type TupleCount<T extends readonly unknown[], U, Acc extends readonly unknown[] = []> =
|
|
727
|
+
T extends readonly [infer First, ...infer Rest]
|
|
728
|
+
? (InternalIsEqual<First, U> extends true
|
|
729
|
+
? TupleCount<Rest, U, [...Acc, unknown]>
|
|
730
|
+
: TupleCount<Rest, U, Acc>)
|
|
731
|
+
: Acc['length']
|
|
732
|
+
|
|
733
|
+
/**
|
|
734
|
+
* Find the first index of an element that extends a predicate type.
|
|
735
|
+
*
|
|
736
|
+
* @example
|
|
737
|
+
* ```
|
|
738
|
+
* // Expect: 1
|
|
739
|
+
* type Example1 = TupleFindIndex<[1, 'a', true], string>
|
|
740
|
+
* // Expect: -1
|
|
741
|
+
* type Example2 = TupleFindIndex<[1, 2], string>
|
|
742
|
+
* ```
|
|
743
|
+
*/
|
|
744
|
+
export type TupleFindIndex<T extends readonly unknown[], P, Count extends readonly unknown[] = []> =
|
|
745
|
+
T extends readonly [infer First, ...infer Rest]
|
|
746
|
+
? (First extends P
|
|
747
|
+
? Count['length']
|
|
748
|
+
: TupleFindIndex<Rest, P, [...Count, unknown]>)
|
|
749
|
+
: -1
|
|
750
|
+
|
|
751
|
+
/**
|
|
752
|
+
* Get the head index (0 for non-empty tuples).
|
|
753
|
+
*
|
|
754
|
+
* @example
|
|
755
|
+
* ```
|
|
756
|
+
* // Expect: 0
|
|
757
|
+
* type Example1 = TupleHeadIndex<[1, 2]>
|
|
758
|
+
* // Expect: never
|
|
759
|
+
* type Example2 = TupleHeadIndex<[]>
|
|
760
|
+
* ```
|
|
761
|
+
*/
|
|
762
|
+
export type TupleHeadIndex<T extends readonly unknown[]> = T extends [] ? never : 0
|
|
763
|
+
|
|
764
|
+
/**
|
|
765
|
+
* Get the last index of a tuple.
|
|
766
|
+
*
|
|
767
|
+
* @example
|
|
768
|
+
* ```
|
|
769
|
+
* // Expect: 2
|
|
770
|
+
* type Example1 = TupleLastIndex<[1, 2, 3]>
|
|
771
|
+
* // Expect: never
|
|
772
|
+
* type Example2 = TupleLastIndex<[]>
|
|
773
|
+
* ```
|
|
774
|
+
*/
|
|
775
|
+
export type TupleLastIndex<T extends readonly unknown[]> =
|
|
776
|
+
T extends []
|
|
777
|
+
? never
|
|
778
|
+
: InternalTupleBuildArray<T['length']> extends [unknown, ...infer Rest]
|
|
779
|
+
? Rest['length']
|
|
780
|
+
: never
|
|
781
|
+
|
|
782
|
+
/**
|
|
783
|
+
* Get the index of the minimum numeric literal in a tuple of numbers.
|
|
784
|
+
*
|
|
785
|
+
* @example
|
|
786
|
+
* ```
|
|
787
|
+
* // Expect: 1
|
|
788
|
+
* type Example1 = TupleMinIndex<[3, 1, 2]>
|
|
789
|
+
* // Expect: 0
|
|
790
|
+
* type Example2 = TupleMinIndex<[1]>
|
|
791
|
+
* ```
|
|
792
|
+
*/
|
|
793
|
+
export type TupleMinIndex<T extends readonly number[], Count extends readonly unknown[] = [], MinIndex extends number = 0, MinValue extends number | null = null> =
|
|
794
|
+
T extends readonly [infer First extends number, ...infer Rest extends number[]]
|
|
795
|
+
? (MinValue extends null
|
|
796
|
+
? TupleMinIndex<Rest, [...Count, unknown], Count['length'], First>
|
|
797
|
+
: (MinValue extends number
|
|
798
|
+
? (InternalTupleBuildArray<First> extends [...InternalTupleBuildArray<MinValue>, ...infer _]
|
|
799
|
+
? TupleMinIndex<Rest, [...Count, unknown], MinIndex, MinValue>
|
|
800
|
+
: TupleMinIndex<Rest, [...Count, unknown], Count['length'], First>)
|
|
801
|
+
: MinIndex))
|
|
802
|
+
: MinIndex
|
|
803
|
+
|
|
804
|
+
/**
|
|
805
|
+
* Get the index of the maximum numeric literal in a tuple of numbers.
|
|
806
|
+
*
|
|
807
|
+
* @example
|
|
808
|
+
* ```
|
|
809
|
+
* // Expect: 0
|
|
810
|
+
* type Example1 = TupleMaxIndex<[3, 1, 2]>
|
|
811
|
+
* // Expect: 0
|
|
812
|
+
* type Example2 = TupleMaxIndex<[1]>
|
|
813
|
+
* ```
|
|
814
|
+
*/
|
|
815
|
+
export type TupleMaxIndex<T extends readonly number[], Count extends readonly unknown[] = [], MaxIndex extends number = 0, MaxValue extends number | null = null> =
|
|
816
|
+
T extends readonly [infer First extends number, ...infer Rest extends number[]]
|
|
817
|
+
? (MaxValue extends null
|
|
818
|
+
? TupleMaxIndex<Rest, [...Count, unknown], Count['length'], First>
|
|
819
|
+
: (MaxValue extends number
|
|
820
|
+
? (InternalTupleBuildArray<MaxValue> extends [...InternalTupleBuildArray<First>, ...infer _]
|
|
821
|
+
? TupleMaxIndex<Rest, [...Count, unknown], MaxIndex, MaxValue>
|
|
822
|
+
: TupleMaxIndex<Rest, [...Count, unknown], Count['length'], First>)
|
|
823
|
+
: MaxIndex))
|
|
824
|
+
: MaxIndex
|
|
825
|
+
|
|
826
|
+
/**
|
|
827
|
+
* Find the first element that extends a predicate type.
|
|
828
|
+
*
|
|
829
|
+
* @example
|
|
830
|
+
* ```
|
|
831
|
+
* // Expect: 'a'
|
|
832
|
+
* type Example1 = TupleFind<[1, 'a', true], string>
|
|
833
|
+
* // Expect: never
|
|
834
|
+
* type Example2 = TupleFind<[1, 2], string>
|
|
835
|
+
* ```
|
|
836
|
+
*/
|
|
837
|
+
export type TupleFind<T extends readonly unknown[], P> =
|
|
838
|
+
T extends readonly [infer First, ...infer Rest]
|
|
839
|
+
? (First extends P ? First : TupleFind<Rest, P>)
|
|
840
|
+
: never
|
|
841
|
+
|
|
842
|
+
/**
|
|
843
|
+
* Check if a tuple has duplicate elements.
|
|
844
|
+
*
|
|
845
|
+
* @example
|
|
846
|
+
* ```
|
|
847
|
+
* // Expect: true
|
|
848
|
+
* type Example1 = TupleHasDuplicates<[1, 2, 1]>
|
|
849
|
+
* // Expect: false
|
|
850
|
+
* type Example2 = TupleHasDuplicates<[1, 2, 3]>
|
|
851
|
+
* ```
|
|
852
|
+
*/
|
|
853
|
+
export type TupleHasDuplicates<T extends readonly unknown[]> =
|
|
854
|
+
T extends readonly [infer First, ...infer Rest]
|
|
855
|
+
? (TupleIncludes<Rest, First> extends true ? true : TupleHasDuplicates<Rest>)
|
|
856
|
+
: false
|
|
857
|
+
|
|
858
|
+
/**
|
|
859
|
+
* Get all indices where a value appears in a tuple.
|
|
860
|
+
*
|
|
861
|
+
* @example
|
|
862
|
+
* ```
|
|
863
|
+
* // Expect: [0, 2]
|
|
864
|
+
* type Example1 = TupleIndicesOf<[1, 2, 1], 1>
|
|
865
|
+
* // Expect: []
|
|
866
|
+
* type Example2 = TupleIndicesOf<[1, 2, 3], 4>
|
|
867
|
+
* ```
|
|
868
|
+
*/
|
|
869
|
+
export type TupleIndicesOf<T extends readonly unknown[], U, Count extends readonly unknown[] = [], Acc extends readonly number[] = []> =
|
|
870
|
+
T extends readonly [infer First, ...infer Rest]
|
|
871
|
+
? (InternalIsEqual<First, U> extends true
|
|
872
|
+
? TupleIndicesOf<Rest, U, [...Count, unknown], [...Acc, Count['length']]>
|
|
873
|
+
: TupleIndicesOf<Rest, U, [...Count, unknown], Acc>)
|
|
874
|
+
: Acc
|
|
875
|
+
|
|
876
|
+
/**
|
|
877
|
+
* Alias of TupleIndexOf.
|
|
878
|
+
*
|
|
879
|
+
* @example
|
|
880
|
+
* ```
|
|
881
|
+
* // Expect: 0
|
|
882
|
+
* type Example1 = TupleFirstIndexOf<[1, 2], 1>
|
|
883
|
+
* // Expect: -1
|
|
884
|
+
* type Example2 = TupleFirstIndexOf<[1, 2], 3>
|
|
885
|
+
* ```
|
|
886
|
+
*/
|
|
887
|
+
export type TupleFirstIndexOf<T extends readonly unknown[], U> = TupleIndexOf<T, U>
|
|
888
|
+
|
|
889
|
+
/**
|
|
890
|
+
* Get the last index for each element in the tuple.
|
|
891
|
+
*
|
|
892
|
+
* @example
|
|
893
|
+
* ```
|
|
894
|
+
* // Expect: [2, 1, 2]
|
|
895
|
+
* type Example1 = TupleLastIndexOfAll<[1, 2, 1]>
|
|
896
|
+
* // Expect: []
|
|
897
|
+
* type Example2 = TupleLastIndexOfAll<[]>
|
|
898
|
+
* ```
|
|
899
|
+
*/
|
|
900
|
+
export type TupleLastIndexOfAll<T extends readonly unknown[]> =
|
|
901
|
+
T extends readonly [infer First, ...infer Rest]
|
|
902
|
+
? [TupleLastIndexOf<T, First>, ...TupleLastIndexOfAll<Rest>]
|
|
903
|
+
: []
|
|
904
|
+
|
|
905
|
+
type InternalTupleFindLastIndex<T extends readonly unknown[], P, Count extends readonly unknown[] = [], Last extends number = -1> =
|
|
906
|
+
T extends readonly [infer First, ...infer Rest]
|
|
907
|
+
? InternalTupleFindLastIndex<Rest, P, [...Count, unknown], First extends P ? Count['length'] : Last>
|
|
908
|
+
: Last
|
|
909
|
+
/**
|
|
910
|
+
* Find the last index of an element that extends a predicate type.
|
|
911
|
+
*
|
|
912
|
+
* @example
|
|
913
|
+
* ```
|
|
914
|
+
* // Expect: 2
|
|
915
|
+
* type Example1 = TupleFindLastIndex<[1, 'a', 'b'], string>
|
|
916
|
+
* // Expect: -1
|
|
917
|
+
* type Example2 = TupleFindLastIndex<[1, 2], string>
|
|
918
|
+
* ```
|
|
919
|
+
*/
|
|
920
|
+
export type TupleFindLastIndex<T extends readonly unknown[], P> = InternalTupleFindLastIndex<T, P>
|
|
921
|
+
|
|
922
|
+
// ============================================================================
|
|
923
|
+
// Generation
|
|
924
|
+
// ============================================================================
|
|
925
|
+
|
|
926
|
+
type InternalAdd<A extends number, B extends number> =
|
|
927
|
+
[...InternalTupleBuildArray<A>, ...InternalTupleBuildArray<B>]['length']
|
|
928
|
+
|
|
929
|
+
type InternalSubtract<A extends number, B extends number> =
|
|
930
|
+
InternalTupleBuildArray<A> extends [...infer Rest, ...InternalTupleBuildArray<B>]
|
|
931
|
+
? Rest['length']
|
|
932
|
+
: never
|
|
933
|
+
|
|
934
|
+
type InternalTupleRepeat<T, N extends number, Acc extends readonly unknown[] = []> =
|
|
935
|
+
Acc['length'] extends N
|
|
936
|
+
? Acc
|
|
937
|
+
: InternalTupleRepeat<T, N, [...Acc, T]>
|
|
938
|
+
|
|
939
|
+
/**
|
|
940
|
+
* Repeat an element type N times.
|
|
941
|
+
*
|
|
942
|
+
* @example
|
|
943
|
+
* ```
|
|
944
|
+
* // Expect: [string, string, string]
|
|
945
|
+
* type Example1 = TupleRepeat<string, 3>
|
|
946
|
+
* // Expect: []
|
|
947
|
+
* type Example2 = TupleRepeat<number, 0>
|
|
948
|
+
* ```
|
|
949
|
+
*/
|
|
950
|
+
export type TupleRepeat<T, N extends number> = InternalTupleRepeat<T, N>
|
|
951
|
+
|
|
952
|
+
/**
|
|
953
|
+
* Create a numeric range tuple from Start to End (inclusive).
|
|
954
|
+
*
|
|
955
|
+
* @example
|
|
956
|
+
* ```
|
|
957
|
+
* // Expect: [1, 2, 3]
|
|
958
|
+
* type Example1 = TupleRange<1, 3>
|
|
959
|
+
* // Expect: [0]
|
|
960
|
+
* type Example2 = TupleRange<0, 0>
|
|
961
|
+
* ```
|
|
962
|
+
*/
|
|
963
|
+
export type TupleRange<Start extends number, End extends number, Acc extends readonly number[] = [], Current extends number = Start> =
|
|
964
|
+
InternalTupleBuildArray<End> extends [...InternalTupleBuildArray<Current>, ...infer _]
|
|
965
|
+
? (InternalIsEqual<Current, End> extends true
|
|
966
|
+
? [...Acc, Current]
|
|
967
|
+
: TupleRange<Start, End, [...Acc, Current], InternalAdd<Current, 1> extends number ? InternalAdd<Current, 1> : never>)
|
|
968
|
+
: Acc
|
|
969
|
+
|
|
970
|
+
/**
|
|
971
|
+
* Fill a tuple of length N with element type T.
|
|
972
|
+
*
|
|
973
|
+
* @example
|
|
974
|
+
* ```
|
|
975
|
+
* // Expect: [number, number]
|
|
976
|
+
* type Example1 = TupleFill<number, 2>
|
|
977
|
+
* // Expect: []
|
|
978
|
+
* type Example2 = TupleFill<string, 0>
|
|
979
|
+
* ```
|
|
980
|
+
*/
|
|
981
|
+
export type TupleFill<T, N extends number> = TupleRepeat<T, N>
|
|
982
|
+
|
|
983
|
+
/**
|
|
984
|
+
* Build a tuple of length N from element type T.
|
|
985
|
+
*
|
|
986
|
+
* @example
|
|
987
|
+
* ```
|
|
988
|
+
* // Expect: [boolean, boolean]
|
|
989
|
+
* type Example1 = TupleOf<boolean, 2>
|
|
990
|
+
* // Expect: []
|
|
991
|
+
* type Example2 = TupleOf<string, 0>
|
|
992
|
+
* ```
|
|
993
|
+
*/
|
|
994
|
+
export type TupleOf<T, N extends number> = TupleRepeat<T, N>
|
|
995
|
+
|
|
996
|
+
/**
|
|
997
|
+
* Alias of TupleOf.
|
|
998
|
+
*
|
|
999
|
+
* @example
|
|
1000
|
+
* ```
|
|
1001
|
+
* // Expect: [1, 1]
|
|
1002
|
+
* type Example1 = TupleMake<1, 2>
|
|
1003
|
+
* // Expect: []
|
|
1004
|
+
* type Example2 = TupleMake<string, 0>
|
|
1005
|
+
* ```
|
|
1006
|
+
*/
|
|
1007
|
+
export type TupleMake<T, N extends number> = TupleOf<T, N>
|
|
1008
|
+
|
|
1009
|
+
/**
|
|
1010
|
+
* Pad a tuple at the start to length N.
|
|
1011
|
+
*
|
|
1012
|
+
* @example
|
|
1013
|
+
* ```
|
|
1014
|
+
* // Expect: [0, 1, 2]
|
|
1015
|
+
* type Example1 = TuplePadStart<[1, 2], 3, 0>
|
|
1016
|
+
* // Expect: [1]
|
|
1017
|
+
* type Example2 = TuplePadStart<[1], 1, 0>
|
|
1018
|
+
* ```
|
|
1019
|
+
*/
|
|
1020
|
+
export type TuplePadStart<T extends readonly unknown[], N extends number, Fill = undefined> =
|
|
1021
|
+
TupleLength<T> extends N
|
|
1022
|
+
? T
|
|
1023
|
+
: (TupleLength<T> extends infer L
|
|
1024
|
+
? (L extends number
|
|
1025
|
+
? (InternalTupleBuildArray<L> extends [...InternalTupleBuildArray<N>, ...infer _]
|
|
1026
|
+
? T
|
|
1027
|
+
: TuplePadStart<[Fill, ...T], N, Fill>)
|
|
1028
|
+
: T)
|
|
1029
|
+
: T)
|
|
1030
|
+
|
|
1031
|
+
/**
|
|
1032
|
+
* Pad a tuple at the end to length N.
|
|
1033
|
+
*
|
|
1034
|
+
* @example
|
|
1035
|
+
* ```
|
|
1036
|
+
* // Expect: [1, 2, 0]
|
|
1037
|
+
* type Example1 = TuplePadEnd<[1, 2], 3, 0>
|
|
1038
|
+
* // Expect: [1]
|
|
1039
|
+
* type Example2 = TuplePadEnd<[1], 1, 0>
|
|
1040
|
+
* ```
|
|
1041
|
+
*/
|
|
1042
|
+
export type TuplePadEnd<T extends readonly unknown[], N extends number, Fill = undefined> =
|
|
1043
|
+
TupleLength<T> extends N
|
|
1044
|
+
? T
|
|
1045
|
+
: (TupleLength<T> extends infer L
|
|
1046
|
+
? (L extends number
|
|
1047
|
+
? (InternalTupleBuildArray<L> extends [...InternalTupleBuildArray<N>, ...infer _]
|
|
1048
|
+
? T
|
|
1049
|
+
: TuplePadEnd<[...T, Fill], N, Fill>)
|
|
1050
|
+
: T)
|
|
1051
|
+
: T)
|
|
1052
|
+
|
|
1053
|
+
type InternalInsertEach<T, P extends readonly unknown[]> =
|
|
1054
|
+
P extends readonly [infer First, ...infer Rest]
|
|
1055
|
+
? ([T, First, ...Rest] | [First, ...InternalInsertEach<T, Rest>])
|
|
1056
|
+
: [T]
|
|
1057
|
+
/**
|
|
1058
|
+
* Get all permutations of a tuple as a union of tuples.
|
|
1059
|
+
*
|
|
1060
|
+
* @example
|
|
1061
|
+
* ```
|
|
1062
|
+
* // Expect: [1, 2] | [2, 1]
|
|
1063
|
+
* type Example1 = TuplePermutations<[1, 2]>
|
|
1064
|
+
* // Expect: []
|
|
1065
|
+
* type Example2 = TuplePermutations<[]>
|
|
1066
|
+
* ```
|
|
1067
|
+
*/
|
|
1068
|
+
export type TuplePermutations<T extends readonly unknown[]> =
|
|
1069
|
+
T extends []
|
|
1070
|
+
? []
|
|
1071
|
+
: (T extends readonly [infer First, ...infer Rest]
|
|
1072
|
+
? (TuplePermutations<Rest> extends infer Perm
|
|
1073
|
+
? (Perm extends readonly unknown[]
|
|
1074
|
+
? InternalInsertEach<First, Perm>
|
|
1075
|
+
: never)
|
|
1076
|
+
: never)
|
|
1077
|
+
: never)
|
|
1078
|
+
|
|
1079
|
+
/**
|
|
1080
|
+
* Get all combinations of a tuple as a union of tuples.
|
|
1081
|
+
*
|
|
1082
|
+
* @example
|
|
1083
|
+
* ```
|
|
1084
|
+
* // Expect: [] | [1] | [2] | [1, 2]
|
|
1085
|
+
* type Example1 = TupleCombinations<[1, 2]>
|
|
1086
|
+
* // Expect: []
|
|
1087
|
+
* type Example2 = TupleCombinations<[]>
|
|
1088
|
+
* ```
|
|
1089
|
+
*/
|
|
1090
|
+
export type TupleCombinations<T extends readonly unknown[]> =
|
|
1091
|
+
T extends readonly [infer First, ...infer Rest]
|
|
1092
|
+
? (TupleCombinations<Rest> extends infer Comb
|
|
1093
|
+
? (Comb extends readonly unknown[]
|
|
1094
|
+
? Comb | [First, ...Comb]
|
|
1095
|
+
: never)
|
|
1096
|
+
: never)
|
|
1097
|
+
: []
|
|
1098
|
+
|
|
1099
|
+
/**
|
|
1100
|
+
* Compute the cartesian product of two tuples as a union of pairs.
|
|
1101
|
+
*
|
|
1102
|
+
* @example
|
|
1103
|
+
* ```
|
|
1104
|
+
* // Expect: [1, 'a'] | [1, 'b'] | [2, 'a'] | [2, 'b']
|
|
1105
|
+
* type Example1 = TupleCartesian<[1, 2], ['a', 'b']>
|
|
1106
|
+
* // Expect: never
|
|
1107
|
+
* type Example2 = TupleCartesian<[], ['a']>
|
|
1108
|
+
* ```
|
|
1109
|
+
*/
|
|
1110
|
+
export type TupleCartesian<A extends readonly unknown[], B extends readonly unknown[]> =
|
|
1111
|
+
A extends readonly [infer First, ...infer Rest]
|
|
1112
|
+
? (B extends readonly unknown[]
|
|
1113
|
+
? (B[number] extends infer Item
|
|
1114
|
+
? [First, Item] | TupleCartesian<Rest, B>
|
|
1115
|
+
: never)
|
|
1116
|
+
: never)
|
|
1117
|
+
: never
|
|
1118
|
+
|
|
1119
|
+
/**
|
|
1120
|
+
* Get the power set of a tuple as a union of tuples.
|
|
1121
|
+
*
|
|
1122
|
+
* @example
|
|
1123
|
+
* ```
|
|
1124
|
+
* // Expect: [] | [1] | [2] | [1, 2]
|
|
1125
|
+
* type Example1 = TuplePowerSet<[1, 2]>
|
|
1126
|
+
* // Expect: []
|
|
1127
|
+
* type Example2 = TuplePowerSet<[]>
|
|
1128
|
+
* ```
|
|
1129
|
+
*/
|
|
1130
|
+
export type TuplePowerSet<T extends readonly unknown[]> = TupleCombinations<T>
|
|
1131
|
+
|
|
1132
|
+
/**
|
|
1133
|
+
* Intersperse a separator between tuple elements.
|
|
1134
|
+
*
|
|
1135
|
+
* @example
|
|
1136
|
+
* ```
|
|
1137
|
+
* // Expect: [1, 0, 2, 0, 3]
|
|
1138
|
+
* type Example1 = TupleIntersperse<[1, 2, 3], 0>
|
|
1139
|
+
* // Expect: []
|
|
1140
|
+
* type Example2 = TupleIntersperse<[], 0>
|
|
1141
|
+
* ```
|
|
1142
|
+
*/
|
|
1143
|
+
export type TupleIntersperse<T extends readonly unknown[], S> =
|
|
1144
|
+
T extends readonly [infer First, ...infer Rest]
|
|
1145
|
+
? (Rest extends [] ? [First] : [First, S, ...TupleIntersperse<Rest, S>])
|
|
1146
|
+
: []
|
|
1147
|
+
|
|
1148
|
+
/**
|
|
1149
|
+
* Repeat each element N times.
|
|
1150
|
+
*
|
|
1151
|
+
* @example
|
|
1152
|
+
* ```
|
|
1153
|
+
* // Expect: [1, 1, 2, 2]
|
|
1154
|
+
* type Example1 = TupleRepeatEach<[1, 2], 2>
|
|
1155
|
+
* // Expect: []
|
|
1156
|
+
* type Example2 = TupleRepeatEach<[], 3>
|
|
1157
|
+
* ```
|
|
1158
|
+
*/
|
|
1159
|
+
export type TupleRepeatEach<T extends readonly unknown[], N extends number> =
|
|
1160
|
+
T extends readonly [infer First, ...infer Rest]
|
|
1161
|
+
? [...TupleRepeat<First, N>, ...TupleRepeatEach<Rest, N>]
|
|
1162
|
+
: []
|
|
1163
|
+
|
|
1164
|
+
/**
|
|
1165
|
+
* Create a numeric range tuple from Start to End with step.
|
|
1166
|
+
*
|
|
1167
|
+
* @example
|
|
1168
|
+
* ```
|
|
1169
|
+
* // Expect: [1, 3, 5]
|
|
1170
|
+
* type Example1 = TupleRangeStep<1, 5, 2>
|
|
1171
|
+
* // Expect: [0]
|
|
1172
|
+
* type Example2 = TupleRangeStep<0, 0, 1>
|
|
1173
|
+
* ```
|
|
1174
|
+
*/
|
|
1175
|
+
export type TupleRangeStep<Start extends number, End extends number, Step extends number, Acc extends readonly number[] = [], Current extends number = Start> =
|
|
1176
|
+
InternalTupleBuildArray<End> extends [...InternalTupleBuildArray<Current>, ...infer _]
|
|
1177
|
+
? (InternalIsEqual<Current, End> extends true
|
|
1178
|
+
? [...Acc, Current]
|
|
1179
|
+
: TupleRangeStep<Start, End, Step, [...Acc, Current], InternalAdd<Current, Step> extends number ? InternalAdd<Current, Step> : never>)
|
|
1180
|
+
: Acc
|
|
1181
|
+
|
|
1182
|
+
// ============================================================================
|
|
1183
|
+
// Extraction
|
|
1184
|
+
// ============================================================================
|
|
1185
|
+
|
|
1186
|
+
/**
|
|
1187
|
+
* Extract the type of the first element in a tuple.
|
|
1188
|
+
*
|
|
1189
|
+
* @example
|
|
1190
|
+
* ```
|
|
1191
|
+
* // Expect: number
|
|
1192
|
+
* type Example1 = TupleHead<[number, string, boolean]>
|
|
1193
|
+
* // Expect: string
|
|
1194
|
+
* type Example2 = TupleHead<[string]>
|
|
1195
|
+
* ```
|
|
1196
|
+
*/
|
|
1197
|
+
export type TupleHead<T extends readonly unknown[]> = T extends readonly [infer First, ...unknown[]] ? First : never
|
|
1198
|
+
|
|
1199
|
+
/**
|
|
1200
|
+
* Extract the last element from a tuple.
|
|
1201
|
+
*
|
|
1202
|
+
* @example
|
|
1203
|
+
* ```
|
|
1204
|
+
* // Expect: boolean
|
|
1205
|
+
* type Example1 = TupleLast<[number, string, boolean]>
|
|
1206
|
+
* // Expect: string
|
|
1207
|
+
* type Example2 = TupleLast<[string]>
|
|
1208
|
+
* ```
|
|
1209
|
+
*/
|
|
1210
|
+
export type TupleLast<T extends readonly unknown[]> = T extends readonly [...unknown[], infer Last] ? Last : never
|
|
1211
|
+
|
|
1212
|
+
/**
|
|
1213
|
+
* Extract all elements except the first one from a tuple.
|
|
1214
|
+
*
|
|
1215
|
+
* @example
|
|
1216
|
+
* ```
|
|
1217
|
+
* // Expect: [string, boolean]
|
|
1218
|
+
* type Example1 = TupleTail<[number, string, boolean]>
|
|
1219
|
+
* // Expect: []
|
|
1220
|
+
* type Example2 = TupleTail<[string]>
|
|
1221
|
+
* ```
|
|
1222
|
+
*/
|
|
1223
|
+
export type TupleTail<T extends readonly unknown[]> = T extends readonly [unknown, ...infer Rest] ? Rest : []
|
|
1224
|
+
|
|
1225
|
+
/**
|
|
1226
|
+
* Extract all elements except the last one from a tuple.
|
|
1227
|
+
*
|
|
1228
|
+
* @example
|
|
1229
|
+
* ```
|
|
1230
|
+
* // Expect: [number, string]
|
|
1231
|
+
* type Example1 = TuplePrev<[number, string, boolean]>
|
|
1232
|
+
* // Expect: []
|
|
1233
|
+
* type Example2 = TuplePrev<[string]>
|
|
1234
|
+
* ```
|
|
1235
|
+
*/
|
|
1236
|
+
export type TuplePrev<T extends readonly unknown[]> = T extends readonly [...infer Rest, unknown] ? Rest : []
|
|
1237
|
+
|
|
1238
|
+
type InternalAt<T extends readonly unknown[], N extends number, Count extends readonly unknown[] = []> =
|
|
1239
|
+
Count['length'] extends N
|
|
1240
|
+
? TupleHead<T>
|
|
1241
|
+
: InternalAt<TupleTail<T>, N, [...Count, unknown]>
|
|
1242
|
+
/**
|
|
1243
|
+
* Get the element at index N in a tuple.
|
|
1244
|
+
*
|
|
1245
|
+
* @example
|
|
1246
|
+
* ```
|
|
1247
|
+
* // Expect: number
|
|
1248
|
+
* type Example1 = TupleAt<[number, string, boolean], 0>
|
|
1249
|
+
* // Expect: boolean
|
|
1250
|
+
* type Example2 = TupleAt<[number, string, boolean], 2>
|
|
1251
|
+
* ```
|
|
1252
|
+
*/
|
|
1253
|
+
export type TupleAt<T extends readonly unknown[], N extends number> = InternalAt<T, N>
|
|
1254
|
+
|
|
1255
|
+
/**
|
|
1256
|
+
* Take the first N elements from a tuple.
|
|
1257
|
+
*
|
|
1258
|
+
* @example
|
|
1259
|
+
* ```
|
|
1260
|
+
* // Expect: [1, 2]
|
|
1261
|
+
* type Example1 = TupleTake<[1, 2, 3], 2>
|
|
1262
|
+
* // Expect: []
|
|
1263
|
+
* type Example2 = TupleTake<[1, 2], 0>
|
|
1264
|
+
* ```
|
|
1265
|
+
*/
|
|
1266
|
+
export type TupleTake<T extends readonly unknown[], N extends number, Acc extends readonly unknown[] = []> =
|
|
1267
|
+
Acc['length'] extends N
|
|
1268
|
+
? Acc
|
|
1269
|
+
: (T extends readonly [infer First, ...infer Rest]
|
|
1270
|
+
? TupleTake<Rest, N, [...Acc, First]>
|
|
1271
|
+
: Acc)
|
|
1272
|
+
|
|
1273
|
+
/**
|
|
1274
|
+
* Take the last N elements from a tuple.
|
|
1275
|
+
*
|
|
1276
|
+
* @example
|
|
1277
|
+
* ```
|
|
1278
|
+
* // Expect: [2, 3]
|
|
1279
|
+
* type Example1 = TupleTakeLast<[1, 2, 3], 2>
|
|
1280
|
+
* // Expect: []
|
|
1281
|
+
* type Example2 = TupleTakeLast<[1, 2], 0>
|
|
1282
|
+
* ```
|
|
1283
|
+
*/
|
|
1284
|
+
export type TupleTakeLast<T extends readonly unknown[], N extends number> = TupleReverse<TupleTake<TupleReverse<T>, N>>
|
|
1285
|
+
|
|
1286
|
+
type InternalTupleSliceHelper<T extends readonly unknown[], Start extends number, End extends number> =
|
|
1287
|
+
TupleTake<TupleDrop<T, Start>, InternalSubtract<End, Start>>
|
|
1288
|
+
/**
|
|
1289
|
+
* Slice a tuple from Start (inclusive) to End (exclusive).
|
|
1290
|
+
*
|
|
1291
|
+
* @example
|
|
1292
|
+
* ```
|
|
1293
|
+
* // Expect: [2, 3]
|
|
1294
|
+
* type Example1 = TupleSlice<[1, 2, 3, 4], 1, 3>
|
|
1295
|
+
* // Expect: []
|
|
1296
|
+
* type Example2 = TupleSlice<[1, 2], 1, 1>
|
|
1297
|
+
* ```
|
|
1298
|
+
*/
|
|
1299
|
+
export type TupleSlice<T extends readonly unknown[], Start extends number, End extends number> = InternalTupleSliceHelper<T, Start, End>
|
|
1300
|
+
|
|
1301
|
+
/**
|
|
1302
|
+
* Drop the first N elements from a tuple.
|
|
1303
|
+
*
|
|
1304
|
+
* @example
|
|
1305
|
+
* ```
|
|
1306
|
+
* // Expect: [3]
|
|
1307
|
+
* type Example1 = TupleDrop<[1, 2, 3], 2>
|
|
1308
|
+
* // Expect: []
|
|
1309
|
+
* type Example2 = TupleDrop<[1, 2], 2>
|
|
1310
|
+
* ```
|
|
1311
|
+
*/
|
|
1312
|
+
export type TupleDrop<T extends readonly unknown[], N extends number, Count extends readonly unknown[] = []> =
|
|
1313
|
+
Count['length'] extends N
|
|
1314
|
+
? T
|
|
1315
|
+
: (T extends readonly [unknown, ...infer Rest]
|
|
1316
|
+
? TupleDrop<Rest, N, [...Count, unknown]>
|
|
1317
|
+
: [])
|
|
1318
|
+
|
|
1319
|
+
/**
|
|
1320
|
+
* Drop the last N elements from a tuple.
|
|
1321
|
+
*
|
|
1322
|
+
* @example
|
|
1323
|
+
* ```
|
|
1324
|
+
* // Expect: [1]
|
|
1325
|
+
* type Example1 = TupleDropLast<[1, 2, 3], 2>
|
|
1326
|
+
* // Expect: []
|
|
1327
|
+
* type Example2 = TupleDropLast<[1, 2], 2>
|
|
1328
|
+
* ```
|
|
1329
|
+
*/
|
|
1330
|
+
export type TupleDropLast<T extends readonly unknown[], N extends number> = TupleReverse<TupleDrop<TupleReverse<T>, N>>
|
|
1331
|
+
|
|
1332
|
+
/**
|
|
1333
|
+
* Split a tuple at index N into [left, right].
|
|
1334
|
+
*
|
|
1335
|
+
* @example
|
|
1336
|
+
* ```
|
|
1337
|
+
* // Expect: [[1, 2], [3, 4]]
|
|
1338
|
+
* type Example1 = TupleSplitAt<[1, 2, 3, 4], 2>
|
|
1339
|
+
* // Expect: [[], [1]]
|
|
1340
|
+
* type Example2 = TupleSplitAt<[1], 0>
|
|
1341
|
+
* ```
|
|
1342
|
+
*/
|
|
1343
|
+
export type TupleSplitAt<T extends readonly unknown[], N extends number> = [TupleTake<T, N>, TupleDrop<T, N>]
|
|
1344
|
+
|
|
1345
|
+
/**
|
|
1346
|
+
* Pick elements by index list.
|
|
1347
|
+
*
|
|
1348
|
+
* @example
|
|
1349
|
+
* ```
|
|
1350
|
+
* // Expect: [1, 3]
|
|
1351
|
+
* type Example1 = TuplePick<[1, 2, 3], [0, 2]>
|
|
1352
|
+
* // Expect: []
|
|
1353
|
+
* type Example2 = TuplePick<[1, 2], []>
|
|
1354
|
+
* ```
|
|
1355
|
+
*/
|
|
1356
|
+
export type TuplePick<T extends readonly unknown[], I extends readonly number[]> =
|
|
1357
|
+
I extends readonly [infer Index extends number, ...infer Rest extends number[]]
|
|
1358
|
+
? [TupleAt<T, Index>, ...TuplePick<T, Rest>]
|
|
1359
|
+
: []
|
|
1360
|
+
|
|
1361
|
+
/**
|
|
1362
|
+
* Omit elements by index list.
|
|
1363
|
+
*
|
|
1364
|
+
* @example
|
|
1365
|
+
* ```
|
|
1366
|
+
* // Expect: [2]
|
|
1367
|
+
* type Example1 = TupleOmit<[1, 2, 3], [0, 2]>
|
|
1368
|
+
* // Expect: [1, 2]
|
|
1369
|
+
* type Example2 = TupleOmit<[1, 2], []>
|
|
1370
|
+
* ```
|
|
1371
|
+
*/
|
|
1372
|
+
export type TupleOmit<T extends readonly unknown[], I extends readonly number[], Count extends readonly unknown[] = [], Acc extends readonly unknown[] = []> =
|
|
1373
|
+
T extends readonly [infer First, ...infer Rest]
|
|
1374
|
+
? (TupleIncludes<I, Count['length']> extends true
|
|
1375
|
+
? TupleOmit<Rest, I, [...Count, unknown], Acc>
|
|
1376
|
+
: TupleOmit<Rest, I, [...Count, unknown], [...Acc, First]>)
|
|
1377
|
+
: Acc
|
|
1378
|
+
|
|
1379
|
+
/**
|
|
1380
|
+
* Partition a tuple into [matching, rest] by predicate type.
|
|
1381
|
+
*
|
|
1382
|
+
* @example
|
|
1383
|
+
* ```
|
|
1384
|
+
* // Expect: [[1, 2], ['a']]
|
|
1385
|
+
* type Example1 = TuplePartition<[1, 'a', 2], number>
|
|
1386
|
+
* // Expect: [[], [1, 2]]
|
|
1387
|
+
* type Example2 = TuplePartition<[1, 2], string>
|
|
1388
|
+
* ```
|
|
1389
|
+
*/
|
|
1390
|
+
export type TuplePartition<T extends readonly unknown[], P, Matches extends readonly unknown[] = [], Rest extends readonly unknown[] = []> =
|
|
1391
|
+
T extends readonly [infer First, ...infer Tail]
|
|
1392
|
+
? (First extends P
|
|
1393
|
+
? TuplePartition<Tail, P, [...Matches, First], Rest>
|
|
1394
|
+
: TuplePartition<Tail, P, Matches, [...Rest, First]>)
|
|
1395
|
+
: [Matches, Rest]
|
|
1396
|
+
|
|
1397
|
+
/**
|
|
1398
|
+
* Group a tuple of [key, value] pairs by key.
|
|
1399
|
+
*
|
|
1400
|
+
* @example
|
|
1401
|
+
* ```
|
|
1402
|
+
* // Expect: { a: [1, 3]; b: [2] }
|
|
1403
|
+
* type Example1 = TupleGroupBy<[['a', 1], ['b', 2], ['a', 3]]>
|
|
1404
|
+
* // Expect: {}
|
|
1405
|
+
* type Example2 = TupleGroupBy<[]>
|
|
1406
|
+
* ```
|
|
1407
|
+
*/
|
|
1408
|
+
export type TupleGroupBy<T extends readonly (readonly [PropertyKey, unknown])[], Acc extends Record<PropertyKey, unknown[]> = Record<never, never>> =
|
|
1409
|
+
T extends readonly [infer First extends readonly [PropertyKey, unknown], ...infer Rest extends readonly (readonly [PropertyKey, unknown])[]]
|
|
1410
|
+
? TupleGroupBy<Rest, {
|
|
1411
|
+
[K in keyof Acc | First[0]]: K extends First[0]
|
|
1412
|
+
? (K extends keyof Acc ? [...Acc[K], First[1]] : [First[1]])
|
|
1413
|
+
: (K extends keyof Acc ? Acc[K] : never)
|
|
1414
|
+
}>
|
|
1415
|
+
: Acc
|
|
1416
|
+
|
|
1417
|
+
/**
|
|
1418
|
+
* Create a sliding window of size N.
|
|
1419
|
+
*
|
|
1420
|
+
* @example
|
|
1421
|
+
* ```
|
|
1422
|
+
* // Expect: [[1, 2], [2, 3]]
|
|
1423
|
+
* type Example1 = TupleWindow<[1, 2, 3], 2>
|
|
1424
|
+
* // Expect: []
|
|
1425
|
+
* type Example2 = TupleWindow<[1], 2>
|
|
1426
|
+
* ```
|
|
1427
|
+
*/
|
|
1428
|
+
export type TupleWindow<T extends readonly unknown[], N extends number> =
|
|
1429
|
+
TupleTake<T, N> extends infer Head
|
|
1430
|
+
? (Head extends readonly unknown[]
|
|
1431
|
+
? (TupleLength<Head> extends N
|
|
1432
|
+
? [Head, ...TupleWindow<TupleDrop<T, 1>, N>]
|
|
1433
|
+
: [])
|
|
1434
|
+
: [])
|
|
1435
|
+
: []
|
|
1436
|
+
|
|
1437
|
+
/**
|
|
1438
|
+
* Pluck a property from a tuple of objects.
|
|
1439
|
+
*
|
|
1440
|
+
* @example
|
|
1441
|
+
* ```
|
|
1442
|
+
* // Expect: [1, 2]
|
|
1443
|
+
* type Example1 = TuplePluck<[{ id: 1 }, { id: 2 }], 'id'>
|
|
1444
|
+
* // Expect: []
|
|
1445
|
+
* type Example2 = TuplePluck<[], 'id'>
|
|
1446
|
+
* ```
|
|
1447
|
+
*/
|
|
1448
|
+
export type TuplePluck<T extends readonly unknown[], K extends PropertyKey> =
|
|
1449
|
+
T extends readonly [infer First, ...infer Rest]
|
|
1450
|
+
? [First extends Record<K, unknown> ? First[K] : never, ...TuplePluck<Rest, K>]
|
|
1451
|
+
: []
|
|
1452
|
+
|
|
1453
|
+
/**
|
|
1454
|
+
* Alias of TuplePick.
|
|
1455
|
+
*
|
|
1456
|
+
* @example
|
|
1457
|
+
* ```
|
|
1458
|
+
* // Expect: [1]
|
|
1459
|
+
* type Example1 = TuplePickByIndex<[1, 2], [0]>
|
|
1460
|
+
* // Expect: []
|
|
1461
|
+
* type Example2 = TuplePickByIndex<[1, 2], []>
|
|
1462
|
+
* ```
|
|
1463
|
+
*/
|
|
1464
|
+
export type TuplePickByIndex<T extends readonly unknown[], I extends readonly number[]> = TuplePick<T, I>
|
|
1465
|
+
|
|
1466
|
+
/**
|
|
1467
|
+
* Alias of TupleOmit.
|
|
1468
|
+
*
|
|
1469
|
+
* @example
|
|
1470
|
+
* ```
|
|
1471
|
+
* // Expect: [2]
|
|
1472
|
+
* type Example1 = TupleOmitByIndex<[1, 2], [0]>
|
|
1473
|
+
* // Expect: [1, 2]
|
|
1474
|
+
* type Example2 = TupleOmitByIndex<[1, 2], []>
|
|
1475
|
+
* ```
|
|
1476
|
+
*/
|
|
1477
|
+
export type TupleOmitByIndex<T extends readonly unknown[], I extends readonly number[]> = TupleOmit<T, I>
|
|
1478
|
+
|
|
1479
|
+
type InternalTupleSplitHelper<T extends readonly unknown[], Sep, Current extends readonly unknown[] = [], Acc extends readonly unknown[] = []> =
|
|
1480
|
+
T extends readonly [infer First, ...infer Rest]
|
|
1481
|
+
? (InternalIsEqual<First, Sep> extends true
|
|
1482
|
+
? InternalTupleSplitHelper<Rest, Sep, [], [...Acc, Current]>
|
|
1483
|
+
: InternalTupleSplitHelper<Rest, Sep, [...Current, First], Acc>)
|
|
1484
|
+
: [...Acc, Current]
|
|
1485
|
+
/**
|
|
1486
|
+
* Split a tuple by a separator element.
|
|
1487
|
+
*
|
|
1488
|
+
* @example
|
|
1489
|
+
* ```
|
|
1490
|
+
* // Expect: [[1], [2, 3]]
|
|
1491
|
+
* type Example1 = TupleSplitBy<[1, 0, 2, 3], 0>
|
|
1492
|
+
* // Expect: [[]]
|
|
1493
|
+
* type Example2 = TupleSplitBy<[], 0>
|
|
1494
|
+
* ```
|
|
1495
|
+
*/
|
|
1496
|
+
export type TupleSplitBy<T extends readonly unknown[], Sep> = InternalTupleSplitHelper<T, Sep>
|
|
1497
|
+
|
|
1498
|
+
/**
|
|
1499
|
+
* Chunk a tuple by a separator element.
|
|
1500
|
+
*
|
|
1501
|
+
* @example
|
|
1502
|
+
* ```
|
|
1503
|
+
* // Expect: [[1], [2, 3]]
|
|
1504
|
+
* type Example1 = TupleChunkBy<[1, 0, 2, 3], 0>
|
|
1505
|
+
* // Expect: [[]]
|
|
1506
|
+
* type Example2 = TupleChunkBy<[], 0>
|
|
1507
|
+
* ```
|
|
1508
|
+
*/
|
|
1509
|
+
export type TupleChunkBy<T extends readonly unknown[], Sep> = TupleSplitBy<T, Sep>
|
|
1510
|
+
|
|
1511
|
+
// ============================================================================
|
|
1512
|
+
// Manipulation
|
|
1513
|
+
// ============================================================================
|
|
1514
|
+
|
|
1515
|
+
/**
|
|
1516
|
+
* Prepend an element to a tuple.
|
|
1517
|
+
*
|
|
1518
|
+
* @example
|
|
1519
|
+
* ```
|
|
1520
|
+
* // Expect: [number, string, boolean]
|
|
1521
|
+
* type Example1 = TuplePrepend<[string, boolean], number>
|
|
1522
|
+
* // Expect: [number]
|
|
1523
|
+
* type Example2 = TuplePrepend<[], number>
|
|
1524
|
+
* ```
|
|
1525
|
+
*/
|
|
1526
|
+
export type TuplePrepend<T extends readonly unknown[], E> = [E, ...T]
|
|
1527
|
+
|
|
1528
|
+
/**
|
|
1529
|
+
* Append an element to a tuple.
|
|
1530
|
+
*
|
|
1531
|
+
* @example
|
|
1532
|
+
* ```
|
|
1533
|
+
* // Expect: [string, boolean, number]
|
|
1534
|
+
* type Example1 = TupleAppend<[string, boolean], number>
|
|
1535
|
+
* // Expect: [number]
|
|
1536
|
+
* type Example2 = TupleAppend<[], number>
|
|
1537
|
+
* ```
|
|
1538
|
+
*/
|
|
1539
|
+
export type TupleAppend<T extends readonly unknown[], E> = [...T, E]
|
|
1540
|
+
|
|
1541
|
+
type InternalReverse<T extends readonly unknown[], Acc extends readonly unknown[] = []> =
|
|
1542
|
+
T extends readonly [infer First, ...infer Rest]
|
|
1543
|
+
? InternalReverse<Rest, [First, ...Acc]>
|
|
1544
|
+
: Acc
|
|
1545
|
+
/**
|
|
1546
|
+
* Reverse the order of elements in a tuple.
|
|
1547
|
+
*
|
|
1548
|
+
* @example
|
|
1549
|
+
* ```
|
|
1550
|
+
* // Expect: [boolean, string, number]
|
|
1551
|
+
* type Example1 = TupleReverse<[number, string, boolean]>
|
|
1552
|
+
* // Expect: []
|
|
1553
|
+
* type Example2 = TupleReverse<[]>
|
|
1554
|
+
* ```
|
|
1555
|
+
*/
|
|
1556
|
+
export type TupleReverse<T extends readonly unknown[]> = InternalReverse<T>
|
|
1557
|
+
|
|
1558
|
+
/**
|
|
1559
|
+
* Concatenate two tuples.
|
|
1560
|
+
*
|
|
1561
|
+
* @example
|
|
1562
|
+
* ```
|
|
1563
|
+
* // Expect: [1, 2, 3]
|
|
1564
|
+
* type Example1 = TupleConcat<[1, 2], [3]>
|
|
1565
|
+
* // Expect: [1]
|
|
1566
|
+
* type Example2 = TupleConcat<[1], []>
|
|
1567
|
+
* ```
|
|
1568
|
+
*/
|
|
1569
|
+
export type TupleConcat<A extends readonly unknown[], B extends readonly unknown[]> = [...A, ...B]
|
|
1570
|
+
|
|
1571
|
+
/**
|
|
1572
|
+
* Flatten a tuple by one level.
|
|
1573
|
+
*
|
|
1574
|
+
* @example
|
|
1575
|
+
* ```
|
|
1576
|
+
* // Expect: [1, 2, 3]
|
|
1577
|
+
* type Example1 = TupleFlatten<[[1, 2], [3]]>
|
|
1578
|
+
* // Expect: [1, 2]
|
|
1579
|
+
* type Example2 = TupleFlatten<[1, [2]]>
|
|
1580
|
+
* ```
|
|
1581
|
+
*/
|
|
1582
|
+
export type TupleFlatten<T extends readonly unknown[]> =
|
|
1583
|
+
T extends readonly [infer First, ...infer Rest]
|
|
1584
|
+
? (First extends readonly unknown[]
|
|
1585
|
+
? [...First, ...TupleFlatten<Rest>]
|
|
1586
|
+
: [First, ...TupleFlatten<Rest>])
|
|
1587
|
+
: []
|
|
1588
|
+
|
|
1589
|
+
/**
|
|
1590
|
+
* Prepend an element to each tuple in a tuple of tuples.
|
|
1591
|
+
*
|
|
1592
|
+
* @example
|
|
1593
|
+
* ```
|
|
1594
|
+
* // Expect: [[0, 1], [0, 2]]
|
|
1595
|
+
* type Example1 = TuplePrependAll<[[1], [2]], 0>
|
|
1596
|
+
* // Expect: []
|
|
1597
|
+
* type Example2 = TuplePrependAll<[], 0>
|
|
1598
|
+
* ```
|
|
1599
|
+
*/
|
|
1600
|
+
export type TuplePrependAll<T extends readonly unknown[][], E> =
|
|
1601
|
+
T extends readonly [infer First extends readonly unknown[], ...infer Rest extends readonly unknown[][]]
|
|
1602
|
+
? [[E, ...First], ...TuplePrependAll<Rest, E>]
|
|
1603
|
+
: []
|
|
1604
|
+
|
|
1605
|
+
/**
|
|
1606
|
+
* Append an element to each tuple in a tuple of tuples.
|
|
1607
|
+
*
|
|
1608
|
+
* @example
|
|
1609
|
+
* ```
|
|
1610
|
+
* // Expect: [[1, 0], [2, 0]]
|
|
1611
|
+
* type Example1 = TupleAppendAll<[[1], [2]], 0>
|
|
1612
|
+
* // Expect: []
|
|
1613
|
+
* type Example2 = TupleAppendAll<[], 0>
|
|
1614
|
+
* ```
|
|
1615
|
+
*/
|
|
1616
|
+
export type TupleAppendAll<T extends readonly unknown[][], E> =
|
|
1617
|
+
T extends readonly [infer First extends readonly unknown[], ...infer Rest extends readonly unknown[][]]
|
|
1618
|
+
? [[...First, E], ...TupleAppendAll<Rest, E>]
|
|
1619
|
+
: []
|
|
1620
|
+
|
|
1621
|
+
/**
|
|
1622
|
+
* Map a tuple using a mapper function type.
|
|
1623
|
+
*
|
|
1624
|
+
* @example
|
|
1625
|
+
* ```
|
|
1626
|
+
* // Expect: [string, string]
|
|
1627
|
+
* type Example1 = TupleMap<[1, 2], (value: number) => string>
|
|
1628
|
+
* // Expect: []
|
|
1629
|
+
* type Example2 = TupleMap<[], (value: number) => string>
|
|
1630
|
+
* ```
|
|
1631
|
+
*/
|
|
1632
|
+
export type TupleMap<T extends readonly unknown[], Mapper extends (value: unknown, index: number, tuple: readonly unknown[]) => unknown> = {
|
|
1633
|
+
[K in keyof T]: Mapper extends (value: T[K], index: number, tuple: T) => infer R ? R : never
|
|
1634
|
+
}
|
|
1635
|
+
|
|
1636
|
+
/**
|
|
1637
|
+
* Filter a tuple by a predicate type.
|
|
1638
|
+
*
|
|
1639
|
+
* @example
|
|
1640
|
+
* ```
|
|
1641
|
+
* // Expect: [1, 2]
|
|
1642
|
+
* type Example1 = TupleFilter<[1, 'a', 2], number>
|
|
1643
|
+
* // Expect: []
|
|
1644
|
+
* type Example2 = TupleFilter<[true, false], string>
|
|
1645
|
+
* ```
|
|
1646
|
+
*/
|
|
1647
|
+
export type TupleFilter<T extends readonly unknown[], P, Acc extends readonly unknown[] = []> =
|
|
1648
|
+
T extends readonly [infer First, ...infer Rest]
|
|
1649
|
+
? (First extends P
|
|
1650
|
+
? TupleFilter<Rest, P, [...Acc, First]>
|
|
1651
|
+
: TupleFilter<Rest, P, Acc>)
|
|
1652
|
+
: Acc
|
|
1653
|
+
|
|
1654
|
+
type InternalTupleZipHelper<A extends readonly unknown[], B extends readonly unknown[]> =
|
|
1655
|
+
A extends readonly [infer FirstA, ...infer RestA]
|
|
1656
|
+
? (B extends readonly [infer FirstB, ...infer RestB]
|
|
1657
|
+
? [[FirstA, FirstB], ...InternalTupleZipHelper<RestA, RestB>]
|
|
1658
|
+
: [])
|
|
1659
|
+
: []
|
|
1660
|
+
/**
|
|
1661
|
+
* Zip two tuples into a tuple of pairs.
|
|
1662
|
+
*
|
|
1663
|
+
* @example
|
|
1664
|
+
* ```
|
|
1665
|
+
* // Expect: [[1, 'a'], [2, 'b']]
|
|
1666
|
+
* type Example1 = TupleZip<[1, 2], ['a', 'b']>
|
|
1667
|
+
* // Expect: []
|
|
1668
|
+
* type Example2 = TupleZip<[], ['a']>
|
|
1669
|
+
* ```
|
|
1670
|
+
*/
|
|
1671
|
+
export type TupleZip<A extends readonly unknown[], B extends readonly unknown[]> = InternalTupleZipHelper<A, B>
|
|
1672
|
+
|
|
1673
|
+
type InternalTupleUnzipHelper<T extends readonly unknown[], Left extends readonly unknown[] = [], Right extends readonly unknown[] = []> =
|
|
1674
|
+
T extends readonly [infer First, ...infer Rest]
|
|
1675
|
+
? (First extends readonly [infer L, infer R]
|
|
1676
|
+
? InternalTupleUnzipHelper<Rest, [...Left, L], [...Right, R]>
|
|
1677
|
+
: InternalTupleUnzipHelper<Rest, Left, Right>)
|
|
1678
|
+
: [Left, Right]
|
|
1679
|
+
/**
|
|
1680
|
+
* Unzip a tuple of pairs into two tuples.
|
|
1681
|
+
*
|
|
1682
|
+
* @example
|
|
1683
|
+
* ```
|
|
1684
|
+
* // Expect: [[1, 2], ['a', 'b']]
|
|
1685
|
+
* type Example1 = TupleUnzip<[[1, 'a'], [2, 'b']]>
|
|
1686
|
+
* // Expect: [[], []]
|
|
1687
|
+
* type Example2 = TupleUnzip<[]>
|
|
1688
|
+
* ```
|
|
1689
|
+
*/
|
|
1690
|
+
export type TupleUnzip<T extends readonly unknown[]> = InternalTupleUnzipHelper<T>
|
|
1691
|
+
|
|
1692
|
+
type InternalTupleDedup<T extends readonly unknown[], Acc extends readonly unknown[] = []> =
|
|
1693
|
+
T extends readonly [infer First, ...infer Rest]
|
|
1694
|
+
? (TupleIncludes<Acc, First> extends true
|
|
1695
|
+
? InternalTupleDedup<Rest, Acc>
|
|
1696
|
+
: InternalTupleDedup<Rest, [...Acc, First]>)
|
|
1697
|
+
: Acc
|
|
1698
|
+
/**
|
|
1699
|
+
* Remove duplicate elements from a tuple.
|
|
1700
|
+
*
|
|
1701
|
+
* @example
|
|
1702
|
+
* ```
|
|
1703
|
+
* // Expect: [1, 2]
|
|
1704
|
+
* type Example1 = TupleUnique<[1, 2, 1]>
|
|
1705
|
+
* // Expect: []
|
|
1706
|
+
* type Example2 = TupleUnique<[]>
|
|
1707
|
+
* ```
|
|
1708
|
+
*/
|
|
1709
|
+
export type TupleUnique<T extends readonly unknown[]> = InternalTupleDedup<T>
|
|
1710
|
+
|
|
1711
|
+
/**
|
|
1712
|
+
* Swap two elements by index.
|
|
1713
|
+
*
|
|
1714
|
+
* @example
|
|
1715
|
+
* ```
|
|
1716
|
+
* // Expect: [2, 1, 3]
|
|
1717
|
+
* type Example1 = TupleSwap<[1, 2, 3], 0, 1>
|
|
1718
|
+
* // Expect: [1, 2, 3]
|
|
1719
|
+
* type Example2 = TupleSwap<[1, 2, 3], 0, 0>
|
|
1720
|
+
* ```
|
|
1721
|
+
*/
|
|
1722
|
+
export type TupleSwap<T extends readonly unknown[], A extends number, B extends number, Count extends readonly unknown[] = [], Acc extends readonly unknown[] = []> =
|
|
1723
|
+
T extends readonly [infer First, ...infer Rest]
|
|
1724
|
+
? (Count['length'] extends A
|
|
1725
|
+
? TupleSwap<Rest, A, B, [...Count, unknown], [...Acc, TupleAt<T, B>]>
|
|
1726
|
+
: (Count['length'] extends B
|
|
1727
|
+
? TupleSwap<Rest, A, B, [...Count, unknown], [...Acc, TupleAt<T, A>]>
|
|
1728
|
+
: TupleSwap<Rest, A, B, [...Count, unknown], [...Acc, First]>))
|
|
1729
|
+
: Acc
|
|
1730
|
+
|
|
1731
|
+
/**
|
|
1732
|
+
* Insert a value at index N.
|
|
1733
|
+
*
|
|
1734
|
+
* @example
|
|
1735
|
+
* ```
|
|
1736
|
+
* // Expect: [1, 0, 2]
|
|
1737
|
+
* type Example1 = TupleInsert<[1, 2], 1, 0>
|
|
1738
|
+
* // Expect: [0, 1]
|
|
1739
|
+
* type Example2 = TupleInsert<[1], 0, 0>
|
|
1740
|
+
* ```
|
|
1741
|
+
*/
|
|
1742
|
+
export type TupleInsert<T extends readonly unknown[], N extends number, V, Acc extends readonly unknown[] = []> =
|
|
1743
|
+
Acc['length'] extends N
|
|
1744
|
+
? [...Acc, V, ...T]
|
|
1745
|
+
: (T extends readonly [infer First, ...infer Rest]
|
|
1746
|
+
? TupleInsert<Rest, N, V, [...Acc, First]>
|
|
1747
|
+
: [...Acc, V])
|
|
1748
|
+
|
|
1749
|
+
/**
|
|
1750
|
+
* Remove the element at index N.
|
|
1751
|
+
*
|
|
1752
|
+
* @example
|
|
1753
|
+
* ```
|
|
1754
|
+
* // Expect: [1, 3]
|
|
1755
|
+
* type Example1 = TupleRemoveAt<[1, 2, 3], 1>
|
|
1756
|
+
* // Expect: [2]
|
|
1757
|
+
* type Example2 = TupleRemoveAt<[2], 0>
|
|
1758
|
+
* ```
|
|
1759
|
+
*/
|
|
1760
|
+
export type TupleRemoveAt<T extends readonly unknown[], N extends number, Count extends readonly unknown[] = [], Acc extends readonly unknown[] = []> =
|
|
1761
|
+
T extends readonly [infer First, ...infer Rest]
|
|
1762
|
+
? (Count['length'] extends N
|
|
1763
|
+
? [...Acc, ...Rest]
|
|
1764
|
+
: TupleRemoveAt<Rest, N, [...Count, unknown], [...Acc, First]>)
|
|
1765
|
+
: Acc
|
|
1766
|
+
|
|
1767
|
+
/**
|
|
1768
|
+
* Replace the element at index N.
|
|
1769
|
+
*
|
|
1770
|
+
* @example
|
|
1771
|
+
* ```
|
|
1772
|
+
* // Expect: [1, 0, 3]
|
|
1773
|
+
* type Example1 = TupleReplaceAt<[1, 2, 3], 1, 0>
|
|
1774
|
+
* // Expect: [0]
|
|
1775
|
+
* type Example2 = TupleReplaceAt<[2], 0, 0>
|
|
1776
|
+
* ```
|
|
1777
|
+
*/
|
|
1778
|
+
export type TupleReplaceAt<T extends readonly unknown[], N extends number, V, Count extends readonly unknown[] = [], Acc extends readonly unknown[] = []> =
|
|
1779
|
+
T extends readonly [infer First, ...infer Rest]
|
|
1780
|
+
? (Count['length'] extends N
|
|
1781
|
+
? [...Acc, V, ...Rest]
|
|
1782
|
+
: TupleReplaceAt<Rest, N, V, [...Count, unknown], [...Acc, First]>)
|
|
1783
|
+
: Acc
|
|
1784
|
+
|
|
1785
|
+
type InternalTupleRotateHelper<T extends readonly unknown[], N extends number> =
|
|
1786
|
+
N extends 0
|
|
1787
|
+
? T
|
|
1788
|
+
: InternalTupleRotateHelper<TupleConcat<TupleTail<T>, [TupleHead<T>]>, InternalSubtract<N, 1>>
|
|
1789
|
+
/**
|
|
1790
|
+
* Rotate a tuple left by N (negative rotates right).
|
|
1791
|
+
*
|
|
1792
|
+
* @example
|
|
1793
|
+
* ```
|
|
1794
|
+
* // Expect: [2, 3, 1]
|
|
1795
|
+
* type Example1 = TupleRotate<[1, 2, 3], 1>
|
|
1796
|
+
* // Expect: [3, 1, 2]
|
|
1797
|
+
* type Example2 = TupleRotate<[1, 2, 3], -1>
|
|
1798
|
+
* ```
|
|
1799
|
+
*/
|
|
1800
|
+
export type TupleRotate<T extends readonly unknown[], N extends number> =
|
|
1801
|
+
`${N}` extends `-${infer P extends number}`
|
|
1802
|
+
? TupleRotateRight<T, P>
|
|
1803
|
+
: InternalTupleRotateHelper<T, N>
|
|
1804
|
+
|
|
1805
|
+
type InternalTupleChunkHelper<T extends readonly unknown[], N extends number, Current extends readonly unknown[] = [], Acc extends readonly unknown[] = []> =
|
|
1806
|
+
T extends readonly [infer First, ...infer Rest]
|
|
1807
|
+
? (Current['length'] extends N
|
|
1808
|
+
? InternalTupleChunkHelper<T, N, [], [...Acc, Current]>
|
|
1809
|
+
: InternalTupleChunkHelper<Rest, N, [...Current, First], Acc>)
|
|
1810
|
+
: (Current extends [] ? Acc : [...Acc, Current])
|
|
1811
|
+
/**
|
|
1812
|
+
* Chunk a tuple into sub-tuples of size N.
|
|
1813
|
+
*
|
|
1814
|
+
* @example
|
|
1815
|
+
* ```
|
|
1816
|
+
* // Expect: [[1, 2], [3]]
|
|
1817
|
+
* type Example1 = TupleChunk<[1, 2, 3], 2>
|
|
1818
|
+
* // Expect: []
|
|
1819
|
+
* type Example2 = TupleChunk<[], 2>
|
|
1820
|
+
* ```
|
|
1821
|
+
*/
|
|
1822
|
+
export type TupleChunk<T extends readonly unknown[], N extends number> = InternalTupleChunkHelper<T, N>
|
|
1823
|
+
|
|
1824
|
+
/**
|
|
1825
|
+
* Remove the first element of a tuple.
|
|
1826
|
+
*
|
|
1827
|
+
* @example
|
|
1828
|
+
* ```
|
|
1829
|
+
* // Expect: [2, 3]
|
|
1830
|
+
* type Example1 = TupleShift<[1, 2, 3]>
|
|
1831
|
+
* // Expect: []
|
|
1832
|
+
* type Example2 = TupleShift<[1]>
|
|
1833
|
+
* ```
|
|
1834
|
+
*/
|
|
1835
|
+
export type TupleShift<T extends readonly unknown[]> = TupleTail<T>
|
|
1836
|
+
|
|
1837
|
+
/**
|
|
1838
|
+
* Remove the last element of a tuple.
|
|
1839
|
+
*
|
|
1840
|
+
* @example
|
|
1841
|
+
* ```
|
|
1842
|
+
* // Expect: [1, 2]
|
|
1843
|
+
* type Example1 = TuplePop<[1, 2, 3]>
|
|
1844
|
+
* // Expect: []
|
|
1845
|
+
* type Example2 = TuplePop<[1]>
|
|
1846
|
+
* ```
|
|
1847
|
+
*/
|
|
1848
|
+
export type TuplePop<T extends readonly unknown[]> = TuplePrev<T>
|
|
1849
|
+
|
|
1850
|
+
/**
|
|
1851
|
+
* Append a value to a tuple.
|
|
1852
|
+
*
|
|
1853
|
+
* @example
|
|
1854
|
+
* ```
|
|
1855
|
+
* // Expect: [1, 2, 3]
|
|
1856
|
+
* type Example1 = TuplePush<[1, 2], 3>
|
|
1857
|
+
* // Expect: [1]
|
|
1858
|
+
* type Example2 = TuplePush<[], 1>
|
|
1859
|
+
* ```
|
|
1860
|
+
*/
|
|
1861
|
+
export type TuplePush<T extends readonly unknown[], V> = TupleAppend<T, V>
|
|
1862
|
+
|
|
1863
|
+
/**
|
|
1864
|
+
* Prepend a value to a tuple.
|
|
1865
|
+
*
|
|
1866
|
+
* @example
|
|
1867
|
+
* ```
|
|
1868
|
+
* // Expect: [0, 1, 2]
|
|
1869
|
+
* type Example1 = TupleUnshift<[1, 2], 0>
|
|
1870
|
+
* // Expect: [1]
|
|
1871
|
+
* type Example2 = TupleUnshift<[], 1>
|
|
1872
|
+
* ```
|
|
1873
|
+
*/
|
|
1874
|
+
export type TupleUnshift<T extends readonly unknown[], V> = TuplePrepend<T, V>
|
|
1875
|
+
|
|
1876
|
+
/**
|
|
1877
|
+
* Reverse a section of a tuple from Start to End (exclusive).
|
|
1878
|
+
*
|
|
1879
|
+
* @example
|
|
1880
|
+
* ```
|
|
1881
|
+
* // Expect: [1, 3, 2, 4]
|
|
1882
|
+
* type Example1 = TupleReverseSection<[1, 2, 3, 4], 1, 3>
|
|
1883
|
+
* // Expect: [1, 2]
|
|
1884
|
+
* type Example2 = TupleReverseSection<[1, 2], 0, 1>
|
|
1885
|
+
* ```
|
|
1886
|
+
*/
|
|
1887
|
+
export type TupleReverseSection<T extends readonly unknown[], Start extends number, End extends number> =
|
|
1888
|
+
TupleConcat<TupleTake<T, Start>, TupleConcat<TupleReverse<TupleSlice<T, Start, End>>, TupleDrop<T, End>>>
|
|
1889
|
+
|
|
1890
|
+
/**
|
|
1891
|
+
* Shuffle a tuple (returns permutations as a union).
|
|
1892
|
+
*
|
|
1893
|
+
* @example
|
|
1894
|
+
* ```
|
|
1895
|
+
* // Expect: [1, 2] | [2, 1]
|
|
1896
|
+
* type Example1 = TupleShuffle<[1, 2]>
|
|
1897
|
+
* // Expect: []
|
|
1898
|
+
* type Example2 = TupleShuffle<[]>
|
|
1899
|
+
* ```
|
|
1900
|
+
*/
|
|
1901
|
+
export type TupleShuffle<T extends readonly unknown[]> = TuplePermutations<T>
|
|
1902
|
+
|
|
1903
|
+
type InternalInsertSorted<V extends number, T extends readonly number[]> =
|
|
1904
|
+
T extends readonly [infer First extends number, ...infer Rest extends number[]]
|
|
1905
|
+
? (InternalTupleBuildArray<V> extends [...InternalTupleBuildArray<First>, ...infer _]
|
|
1906
|
+
? [First, ...InternalInsertSorted<V, Rest>]
|
|
1907
|
+
: [V, First, ...Rest])
|
|
1908
|
+
: [V]
|
|
1909
|
+
/**
|
|
1910
|
+
* Sort a tuple of numbers in ascending order.
|
|
1911
|
+
*
|
|
1912
|
+
* @example
|
|
1913
|
+
* ```
|
|
1914
|
+
* // Expect: [1, 2, 3]
|
|
1915
|
+
* type Example1 = TupleSort<[3, 1, 2]>
|
|
1916
|
+
* // Expect: []
|
|
1917
|
+
* type Example2 = TupleSort<[]>
|
|
1918
|
+
* ```
|
|
1919
|
+
*/
|
|
1920
|
+
export type TupleSort<T extends readonly number[]> =
|
|
1921
|
+
T extends readonly [infer First extends number, ...infer Rest extends number[]]
|
|
1922
|
+
? InternalInsertSorted<First, TupleSort<Rest>>
|
|
1923
|
+
: []
|
|
1924
|
+
|
|
1925
|
+
/**
|
|
1926
|
+
* Stable sort a tuple of numbers in ascending order.
|
|
1927
|
+
*
|
|
1928
|
+
* @example
|
|
1929
|
+
* ```
|
|
1930
|
+
* // Expect: [1, 2, 3]
|
|
1931
|
+
* type Example1 = TupleStableSort<[3, 1, 2]>
|
|
1932
|
+
* // Expect: []
|
|
1933
|
+
* type Example2 = TupleStableSort<[]>
|
|
1934
|
+
* ```
|
|
1935
|
+
*/
|
|
1936
|
+
export type TupleStableSort<T extends readonly number[]> = TupleSort<T>
|
|
1937
|
+
|
|
1938
|
+
/**
|
|
1939
|
+
* Flatten a tuple by one level.
|
|
1940
|
+
*
|
|
1941
|
+
* @example
|
|
1942
|
+
* ```
|
|
1943
|
+
* // Expect: [1, 2]
|
|
1944
|
+
* type Example1 = TupleFlattenOnce<[[1], [2]]>
|
|
1945
|
+
* // Expect: []
|
|
1946
|
+
* type Example2 = TupleFlattenOnce<[]>
|
|
1947
|
+
* ```
|
|
1948
|
+
*/
|
|
1949
|
+
export type TupleFlattenOnce<T extends readonly unknown[]> = TupleFlatten<T>
|
|
1950
|
+
|
|
1951
|
+
/**
|
|
1952
|
+
* Deeply flatten a tuple.
|
|
1953
|
+
*
|
|
1954
|
+
* @example
|
|
1955
|
+
* ```
|
|
1956
|
+
* // Expect: [1, 2, 3]
|
|
1957
|
+
* type Example1 = TupleFlattenDeep<[[1, [2]], 3]>
|
|
1958
|
+
* // Expect: []
|
|
1959
|
+
* type Example2 = TupleFlattenDeep<[]>
|
|
1960
|
+
* ```
|
|
1961
|
+
*/
|
|
1962
|
+
export type TupleFlattenDeep<T extends readonly unknown[]> =
|
|
1963
|
+
T extends readonly [infer First, ...infer Rest]
|
|
1964
|
+
? (First extends readonly unknown[]
|
|
1965
|
+
? [...TupleFlattenDeep<First>, ...TupleFlattenDeep<Rest>]
|
|
1966
|
+
: [First, ...TupleFlattenDeep<Rest>])
|
|
1967
|
+
: []
|
|
1968
|
+
|
|
1969
|
+
/**
|
|
1970
|
+
* Remove falsy values from a tuple.
|
|
1971
|
+
*
|
|
1972
|
+
* @example
|
|
1973
|
+
* ```
|
|
1974
|
+
* // Expect: [1, 'a']
|
|
1975
|
+
* type Example1 = TupleCompact<[0, 1, '', 'a', false]>
|
|
1976
|
+
* // Expect: []
|
|
1977
|
+
* type Example2 = TupleCompact<[]>
|
|
1978
|
+
* ```
|
|
1979
|
+
*/
|
|
1980
|
+
export type TupleCompact<T extends readonly unknown[], Acc extends readonly unknown[] = []> =
|
|
1981
|
+
T extends readonly [infer First, ...infer Rest]
|
|
1982
|
+
? (First extends false | 0 | '' | null | undefined
|
|
1983
|
+
? TupleCompact<Rest, Acc>
|
|
1984
|
+
: TupleCompact<Rest, [...Acc, First]>)
|
|
1985
|
+
: Acc
|
|
1986
|
+
|
|
1987
|
+
/**
|
|
1988
|
+
* Get elements in A that are also in B.
|
|
1989
|
+
*
|
|
1990
|
+
* @example
|
|
1991
|
+
* ```
|
|
1992
|
+
* // Expect: [2]
|
|
1993
|
+
* type Example1 = TupleIntersect<[1, 2, 3], [2, 4]>
|
|
1994
|
+
* // Expect: []
|
|
1995
|
+
* type Example2 = TupleIntersect<[1], [2]>
|
|
1996
|
+
* ```
|
|
1997
|
+
*/
|
|
1998
|
+
export type TupleIntersect<A extends readonly unknown[], B extends readonly unknown[], Acc extends readonly unknown[] = []> =
|
|
1999
|
+
A extends readonly [infer First, ...infer Rest]
|
|
2000
|
+
? (TupleIncludes<B, First> extends true
|
|
2001
|
+
? TupleIntersect<Rest, B, [...Acc, First]>
|
|
2002
|
+
: TupleIntersect<Rest, B, Acc>)
|
|
2003
|
+
: Acc
|
|
2004
|
+
|
|
2005
|
+
/**
|
|
2006
|
+
* Get elements in A that are not in B.
|
|
2007
|
+
*
|
|
2008
|
+
* @example
|
|
2009
|
+
* ```
|
|
2010
|
+
* // Expect: [1, 3]
|
|
2011
|
+
* type Example1 = TupleDifference<[1, 2, 3], [2]>
|
|
2012
|
+
* // Expect: [1]
|
|
2013
|
+
* type Example2 = TupleDifference<[1], [2]>
|
|
2014
|
+
* ```
|
|
2015
|
+
*/
|
|
2016
|
+
export type TupleDifference<A extends readonly unknown[], B extends readonly unknown[], Acc extends readonly unknown[] = []> =
|
|
2017
|
+
A extends readonly [infer First, ...infer Rest]
|
|
2018
|
+
? (TupleIncludes<B, First> extends true
|
|
2019
|
+
? TupleDifference<Rest, B, Acc>
|
|
2020
|
+
: TupleDifference<Rest, B, [...Acc, First]>)
|
|
2021
|
+
: Acc
|
|
2022
|
+
|
|
2023
|
+
/**
|
|
2024
|
+
* Get elements that are in A or B but not both.
|
|
2025
|
+
*
|
|
2026
|
+
* @example
|
|
2027
|
+
* ```
|
|
2028
|
+
* // Expect: [1, 3]
|
|
2029
|
+
* type Example1 = TupleSymmetricDifference<[1, 2], [2, 3]>
|
|
2030
|
+
* // Expect: [1]
|
|
2031
|
+
* type Example2 = TupleSymmetricDifference<[1], []>
|
|
2032
|
+
* ```
|
|
2033
|
+
*/
|
|
2034
|
+
export type TupleSymmetricDifference<A extends readonly unknown[], B extends readonly unknown[]> =
|
|
2035
|
+
TupleConcat<TupleDifference<A, B>, TupleDifference<B, A>>
|
|
2036
|
+
|
|
2037
|
+
/**
|
|
2038
|
+
* Reverse all but the last element of a tuple.
|
|
2039
|
+
*
|
|
2040
|
+
* @example
|
|
2041
|
+
* ```
|
|
2042
|
+
* // Expect: [2, 1, 3]
|
|
2043
|
+
* type Example1 = TupleReverseHead<[1, 2, 3]>
|
|
2044
|
+
* // Expect: []
|
|
2045
|
+
* type Example2 = TupleReverseHead<[]>
|
|
2046
|
+
* ```
|
|
2047
|
+
*/
|
|
2048
|
+
export type TupleReverseHead<T extends readonly unknown[]> =
|
|
2049
|
+
T extends readonly [...infer Rest, infer Last]
|
|
2050
|
+
? [...TupleReverse<Rest>, Last]
|
|
2051
|
+
: []
|
|
2052
|
+
|
|
2053
|
+
/**
|
|
2054
|
+
* Reverse all but the first element of a tuple.
|
|
2055
|
+
*
|
|
2056
|
+
* @example
|
|
2057
|
+
* ```
|
|
2058
|
+
* // Expect: [1, 3, 2]
|
|
2059
|
+
* type Example1 = TupleReverseTail<[1, 2, 3]>
|
|
2060
|
+
* // Expect: []
|
|
2061
|
+
* type Example2 = TupleReverseTail<[]>
|
|
2062
|
+
* ```
|
|
2063
|
+
*/
|
|
2064
|
+
export type TupleReverseTail<T extends readonly unknown[]> =
|
|
2065
|
+
T extends readonly [infer First, ...infer Rest]
|
|
2066
|
+
? [First, ...TupleReverse<Rest>]
|
|
2067
|
+
: []
|
|
2068
|
+
|
|
2069
|
+
type InternalTupleRotateLeft<T extends readonly unknown[], N extends number> =
|
|
2070
|
+
N extends 0
|
|
2071
|
+
? T
|
|
2072
|
+
: InternalTupleRotateLeft<TupleConcat<TupleTail<T>, [TupleHead<T>]>, InternalSubtract<N, 1>>
|
|
2073
|
+
/**
|
|
2074
|
+
* Rotate a tuple left by N.
|
|
2075
|
+
*
|
|
2076
|
+
* @example
|
|
2077
|
+
* ```
|
|
2078
|
+
* // Expect: [2, 3, 1]
|
|
2079
|
+
* type Example1 = TupleRotateLeft<[1, 2, 3], 1>
|
|
2080
|
+
* // Expect: [1, 2]
|
|
2081
|
+
* type Example2 = TupleRotateLeft<[1, 2], 0>
|
|
2082
|
+
* ```
|
|
2083
|
+
*/
|
|
2084
|
+
export type TupleRotateLeft<T extends readonly unknown[], N extends number = 1> = InternalTupleRotateLeft<T, N>
|
|
2085
|
+
|
|
2086
|
+
type InternalTupleRotateRight<T extends readonly unknown[], N extends number> =
|
|
2087
|
+
N extends 0
|
|
2088
|
+
? T
|
|
2089
|
+
: InternalTupleRotateRight<TupleConcat<[TupleLast<T>], TuplePrev<T>>, InternalSubtract<N, 1>>
|
|
2090
|
+
/**
|
|
2091
|
+
* Rotate a tuple right by N.
|
|
2092
|
+
*
|
|
2093
|
+
* @example
|
|
2094
|
+
* ```
|
|
2095
|
+
* // Expect: [3, 1, 2]
|
|
2096
|
+
* type Example1 = TupleRotateRight<[1, 2, 3], 1>
|
|
2097
|
+
* // Expect: [1, 2]
|
|
2098
|
+
* type Example2 = TupleRotateRight<[1, 2], 0>
|
|
2099
|
+
* ```
|
|
2100
|
+
*/
|
|
2101
|
+
export type TupleRotateRight<T extends readonly unknown[], N extends number = 1> = InternalTupleRotateRight<T, N>
|
|
2102
|
+
|
|
2103
|
+
/**
|
|
2104
|
+
* Move an element from index From to index To.
|
|
2105
|
+
*
|
|
2106
|
+
* @example
|
|
2107
|
+
* ```
|
|
2108
|
+
* // Expect: [2, 3, 1]
|
|
2109
|
+
* type Example1 = TupleMove<[1, 2, 3], 0, 2>
|
|
2110
|
+
* // Expect: [1, 2, 3]
|
|
2111
|
+
* type Example2 = TupleMove<[1, 2, 3], 1, 1>
|
|
2112
|
+
* ```
|
|
2113
|
+
*/
|
|
2114
|
+
export type TupleMove<T extends readonly unknown[], From extends number, To extends number> =
|
|
2115
|
+
TupleInsert<TupleRemoveAt<T, From>, To, TupleAt<T, From>>
|
|
2116
|
+
|
|
2117
|
+
/**
|
|
2118
|
+
* Swap each adjacent pair of elements.
|
|
2119
|
+
*
|
|
2120
|
+
* @example
|
|
2121
|
+
* ```
|
|
2122
|
+
* // Expect: [2, 1, 4, 3]
|
|
2123
|
+
* type Example1 = TupleSwapPairs<[1, 2, 3, 4]>
|
|
2124
|
+
* // Expect: [1]
|
|
2125
|
+
* type Example2 = TupleSwapPairs<[1]>
|
|
2126
|
+
* ```
|
|
2127
|
+
*/
|
|
2128
|
+
export type TupleSwapPairs<T extends readonly unknown[]> =
|
|
2129
|
+
T extends readonly [infer A, infer B, ...infer Rest]
|
|
2130
|
+
? [B, A, ...TupleSwapPairs<Rest>]
|
|
2131
|
+
: T
|
|
2132
|
+
|
|
2133
|
+
/**
|
|
2134
|
+
* Interleave two tuples.
|
|
2135
|
+
*
|
|
2136
|
+
* @example
|
|
2137
|
+
* ```
|
|
2138
|
+
* // Expect: [1, 'a', 2, 'b']
|
|
2139
|
+
* type Example1 = TupleInterleave<[1, 2], ['a', 'b']>
|
|
2140
|
+
* // Expect: [1]
|
|
2141
|
+
* type Example2 = TupleInterleave<[1], []>
|
|
2142
|
+
* ```
|
|
2143
|
+
*/
|
|
2144
|
+
export type TupleInterleave<A extends readonly unknown[], B extends readonly unknown[]> =
|
|
2145
|
+
A extends readonly [infer FirstA, ...infer RestA]
|
|
2146
|
+
? (B extends readonly [infer FirstB, ...infer RestB]
|
|
2147
|
+
? [FirstA, FirstB, ...TupleInterleave<RestA, RestB>]
|
|
2148
|
+
: [FirstA, ...TupleInterleave<RestA, []>])
|
|
2149
|
+
: (B extends readonly [infer FirstB, ...infer RestB]
|
|
2150
|
+
? [FirstB, ...TupleInterleave<[], RestB>]
|
|
2151
|
+
: [])
|
|
2152
|
+
|
|
2153
|
+
type InternalTupleZipLongestHelper<A extends readonly unknown[], B extends readonly unknown[], Fill> =
|
|
2154
|
+
A extends readonly [infer FirstA, ...infer RestA]
|
|
2155
|
+
? (B extends readonly [infer FirstB, ...infer RestB]
|
|
2156
|
+
? [[FirstA, FirstB], ...InternalTupleZipLongestHelper<RestA, RestB, Fill>]
|
|
2157
|
+
: [[FirstA, Fill], ...InternalTupleZipLongestHelper<RestA, [], Fill>])
|
|
2158
|
+
: (B extends readonly [infer FirstB, ...infer RestB]
|
|
2159
|
+
? [[Fill, FirstB], ...InternalTupleZipLongestHelper<[], RestB, Fill>]
|
|
2160
|
+
: [])
|
|
2161
|
+
/**
|
|
2162
|
+
* Zip two tuples, filling missing entries.
|
|
2163
|
+
*
|
|
2164
|
+
* @example
|
|
2165
|
+
* ```
|
|
2166
|
+
* // Expect: [[1, 'a'], [2, undefined]]
|
|
2167
|
+
* type Example1 = TupleZipLongest<[1, 2], ['a']>
|
|
2168
|
+
* // Expect: []
|
|
2169
|
+
* type Example2 = TupleZipLongest<[], []>
|
|
2170
|
+
* ```
|
|
2171
|
+
*/
|
|
2172
|
+
export type TupleZipLongest<A extends readonly unknown[], B extends readonly unknown[], Fill = undefined> = InternalTupleZipLongestHelper<A, B, Fill>
|
|
2173
|
+
|
|
2174
|
+
/**
|
|
2175
|
+
* Pad both sides to length N (favoring end for odd remainder).
|
|
2176
|
+
*
|
|
2177
|
+
* @example
|
|
2178
|
+
* ```
|
|
2179
|
+
* // Expect: [0, 1, 2, 0]
|
|
2180
|
+
* type Example1 = TuplePad<[1, 2], 4, 0>
|
|
2181
|
+
* // Expect: [1]
|
|
2182
|
+
* type Example2 = TuplePad<[1], 1, 0>
|
|
2183
|
+
* ```
|
|
2184
|
+
*/
|
|
2185
|
+
export type TuplePad<T extends readonly unknown[], N extends number, Fill = undefined> =
|
|
2186
|
+
TuplePadEnd<TuplePadStart<T, N, Fill>, N, Fill>
|
|
2187
|
+
|
|
2188
|
+
type InternalTupleFlattenDepth<T extends readonly unknown[], Depth extends number> =
|
|
2189
|
+
Depth extends 0
|
|
2190
|
+
? T
|
|
2191
|
+
: (T extends readonly [infer First, ...infer Rest]
|
|
2192
|
+
? (First extends readonly unknown[]
|
|
2193
|
+
? [...InternalTupleFlattenDepth<First, InternalSubtract<Depth, 1>>, ...InternalTupleFlattenDepth<Rest, Depth>]
|
|
2194
|
+
: [First, ...InternalTupleFlattenDepth<Rest, Depth>])
|
|
2195
|
+
: [])
|
|
2196
|
+
/**
|
|
2197
|
+
* Flatten a tuple to a given depth.
|
|
2198
|
+
*
|
|
2199
|
+
* @example
|
|
2200
|
+
* ```
|
|
2201
|
+
* // Expect: [1, 2, [3]]
|
|
2202
|
+
* type Example1 = TupleFlattenToDepth<[[1], [2, [3]]], 1>
|
|
2203
|
+
* // Expect: [1, 2, 3]
|
|
2204
|
+
* type Example2 = TupleFlattenToDepth<[[1], [2, [3]]], 2>
|
|
2205
|
+
* ```
|
|
2206
|
+
*/
|
|
2207
|
+
export type TupleFlattenToDepth<T extends readonly unknown[], Depth extends number> = InternalTupleFlattenDepth<T, Depth>
|
|
2208
|
+
|
|
2209
|
+
// ============================================================================
|
|
2210
|
+
// Conversion
|
|
2211
|
+
// ============================================================================
|
|
2212
|
+
|
|
2213
|
+
/**
|
|
2214
|
+
* Convert a tuple to a union of its element types.
|
|
2215
|
+
*
|
|
2216
|
+
* @example
|
|
2217
|
+
* ```
|
|
2218
|
+
* // Expect: 1 | 2
|
|
2219
|
+
* type Example1 = TupleToUnion<[1, 2]>
|
|
2220
|
+
* // Expect: never
|
|
2221
|
+
* type Example2 = TupleToUnion<[]>
|
|
2222
|
+
* ```
|
|
2223
|
+
*/
|
|
2224
|
+
export type TupleToUnion<T extends readonly unknown[]> = T[number]
|
|
2225
|
+
|
|
2226
|
+
/**
|
|
2227
|
+
* Convert a tuple of keys to an object with identical values.
|
|
2228
|
+
*
|
|
2229
|
+
* @example
|
|
2230
|
+
* ```
|
|
2231
|
+
* // Expect: { a: 'a'; b: 'b' }
|
|
2232
|
+
* type Example1 = TupleToObject<['a', 'b']>
|
|
2233
|
+
* // Expect: {}
|
|
2234
|
+
* type Example2 = TupleToObject<[]>
|
|
2235
|
+
* ```
|
|
2236
|
+
*/
|
|
2237
|
+
export type TupleToObject<T extends readonly PropertyKey[]> = {
|
|
2238
|
+
[K in T[number]]: K
|
|
2239
|
+
}
|
|
2240
|
+
|
|
2241
|
+
/**
|
|
2242
|
+
* Convert a tuple of [key, value] pairs to a record.
|
|
2243
|
+
*
|
|
2244
|
+
* @example
|
|
2245
|
+
* ```
|
|
2246
|
+
* // Expect: { a: 1; b: 2 }
|
|
2247
|
+
* type Example1 = TupleToRecord<[['a', 1], ['b', 2]]>
|
|
2248
|
+
* // Expect: {}
|
|
2249
|
+
* type Example2 = TupleToRecord<[]>
|
|
2250
|
+
* ```
|
|
2251
|
+
*/
|
|
2252
|
+
export type TupleToRecord<T extends readonly (readonly [PropertyKey, unknown])[]> = {
|
|
2253
|
+
[K in T[number]as K extends readonly [infer Key extends PropertyKey, unknown] ? Key : never]: K extends readonly [PropertyKey, infer Value] ? Value : never
|
|
2254
|
+
}
|
|
2255
|
+
|
|
2256
|
+
/**
|
|
2257
|
+
* Join tuple elements into a string with a separator.
|
|
2258
|
+
*
|
|
2259
|
+
* @example
|
|
2260
|
+
* ```
|
|
2261
|
+
* // Expect: 'a-b'
|
|
2262
|
+
* type Example1 = TupleToString<['a', 'b'], '-'>
|
|
2263
|
+
* // Expect: ''
|
|
2264
|
+
* type Example2 = TupleToString<[], '-'>
|
|
2265
|
+
* ```
|
|
2266
|
+
*/
|
|
2267
|
+
export type TupleToString<T extends readonly (string | number | boolean)[], Sep extends string = ''> =
|
|
2268
|
+
T extends readonly [infer First extends string | number | boolean, ...infer Rest extends (string | number | boolean)[]]
|
|
2269
|
+
? Rest extends []
|
|
2270
|
+
? `${First}`
|
|
2271
|
+
: `${First}${Sep}${TupleToString<Rest, Sep>}`
|
|
2272
|
+
: ''
|
|
2273
|
+
|
|
2274
|
+
/**
|
|
2275
|
+
* Convert a tuple to an array of its element union.
|
|
2276
|
+
*
|
|
2277
|
+
* @example
|
|
2278
|
+
* ```
|
|
2279
|
+
* // Expect: Array<1 | 2>
|
|
2280
|
+
* type Example1 = TupleToArray<[1, 2]>
|
|
2281
|
+
* // Expect: Array<never>
|
|
2282
|
+
* type Example2 = TupleToArray<[]>
|
|
2283
|
+
* ```
|
|
2284
|
+
*/
|
|
2285
|
+
export type TupleToArray<T extends readonly unknown[]> = Array<T[number]>
|
|
2286
|
+
|
|
2287
|
+
type InternalUnionToIntersection<U> =
|
|
2288
|
+
(U extends unknown ? (value: U) => void : never) extends (value: infer I) => void
|
|
2289
|
+
? I
|
|
2290
|
+
: never
|
|
2291
|
+
/**
|
|
2292
|
+
* Convert a tuple to an intersection of its elements.
|
|
2293
|
+
*
|
|
2294
|
+
* @example
|
|
2295
|
+
* ```
|
|
2296
|
+
* // Expect: { a: 1 } & { b: 2 }
|
|
2297
|
+
* type Example1 = TupleToIntersection<[{ a: 1 }, { b: 2 }]>
|
|
2298
|
+
* // Expect: unknown
|
|
2299
|
+
* type Example2 = TupleToIntersection<[]>
|
|
2300
|
+
* ```
|
|
2301
|
+
*/
|
|
2302
|
+
export type TupleToIntersection<T extends readonly unknown[]> =
|
|
2303
|
+
InternalUnionToIntersection<T[number]> extends infer R ? (R extends unknown ? R : unknown) : unknown
|
|
2304
|
+
|
|
2305
|
+
/**
|
|
2306
|
+
* Convert a tuple of [key, value] pairs to a Map type.
|
|
2307
|
+
*
|
|
2308
|
+
* @example
|
|
2309
|
+
* ```
|
|
2310
|
+
* // Expect: Map<'a' | 'b', 1 | 2>
|
|
2311
|
+
* type Example1 = TupleToMap<[['a', 1], ['b', 2]]>
|
|
2312
|
+
* // Expect: Map<never, never>
|
|
2313
|
+
* type Example2 = TupleToMap<[]>
|
|
2314
|
+
* ```
|
|
2315
|
+
*/
|
|
2316
|
+
export type TupleToMap<T extends readonly (readonly [PropertyKey, unknown])[]> = Map<
|
|
2317
|
+
T[number] extends readonly [infer Key extends PropertyKey, unknown] ? Key : never,
|
|
2318
|
+
T[number] extends readonly [PropertyKey, infer Value] ? Value : never
|
|
2319
|
+
>
|
|
2320
|
+
|
|
2321
|
+
/**
|
|
2322
|
+
* Convert a tuple to a Set type.
|
|
2323
|
+
*
|
|
2324
|
+
* @example
|
|
2325
|
+
* ```
|
|
2326
|
+
* // Expect: Set<1 | 2>
|
|
2327
|
+
* type Example1 = TupleToSet<[1, 2]>
|
|
2328
|
+
* // Expect: Set<never>
|
|
2329
|
+
* type Example2 = TupleToSet<[]>
|
|
2330
|
+
* ```
|
|
2331
|
+
*/
|
|
2332
|
+
export type TupleToSet<T extends readonly unknown[]> = Set<T[number]>
|
|
2333
|
+
|
|
2334
|
+
/**
|
|
2335
|
+
* Make all tuple elements optional.
|
|
2336
|
+
*
|
|
2337
|
+
* @example
|
|
2338
|
+
* ```
|
|
2339
|
+
* // Expect: [number?, string?]
|
|
2340
|
+
* type Example1 = TupleToOptional<[number, string]>
|
|
2341
|
+
* // Expect: []
|
|
2342
|
+
* type Example2 = TupleToOptional<[]>
|
|
2343
|
+
* ```
|
|
2344
|
+
*/
|
|
2345
|
+
export type TupleToOptional<T extends readonly unknown[]> = { [K in keyof T]?: T[K] }
|
|
2346
|
+
|
|
2347
|
+
/**
|
|
2348
|
+
* Make all tuple elements required.
|
|
2349
|
+
*
|
|
2350
|
+
* @example
|
|
2351
|
+
* ```
|
|
2352
|
+
* // Expect: [number, string]
|
|
2353
|
+
* type Example1 = TupleToRequired<[number?, string?]>
|
|
2354
|
+
* // Expect: []
|
|
2355
|
+
* type Example2 = TupleToRequired<[]>
|
|
2356
|
+
* ```
|
|
2357
|
+
*/
|
|
2358
|
+
export type TupleToRequired<T extends readonly unknown[]> = { [K in keyof T]-?: T[K] }
|
|
2359
|
+
|
|
2360
|
+
/**
|
|
2361
|
+
* Convert a tuple to function parameters (identity).
|
|
2362
|
+
*
|
|
2363
|
+
* @example
|
|
2364
|
+
* ```
|
|
2365
|
+
* // Expect: [number, string]
|
|
2366
|
+
* type Example1 = TupleToFunctionParams<[number, string]>
|
|
2367
|
+
* // Expect: []
|
|
2368
|
+
* type Example2 = TupleToFunctionParams<[]>
|
|
2369
|
+
* ```
|
|
2370
|
+
*/
|
|
2371
|
+
export type TupleToFunctionParams<T extends readonly unknown[]> = T
|
|
2372
|
+
|
|
2373
|
+
/**
|
|
2374
|
+
* Get a function return type from a tuple (last element).
|
|
2375
|
+
*
|
|
2376
|
+
* @example
|
|
2377
|
+
* ```
|
|
2378
|
+
* // Expect: string
|
|
2379
|
+
* type Example1 = TupleToFunctionReturn<[number, string]>
|
|
2380
|
+
* // Expect: never
|
|
2381
|
+
* type Example2 = TupleToFunctionReturn<[]>
|
|
2382
|
+
* ```
|
|
2383
|
+
*/
|
|
2384
|
+
export type TupleToFunctionReturn<T extends readonly unknown[]> = TupleLast<T>
|
|
2385
|
+
|
|
2386
|
+
/**
|
|
2387
|
+
* Convert a tuple to a union of single-element tuples.
|
|
2388
|
+
*
|
|
2389
|
+
* @example
|
|
2390
|
+
* ```
|
|
2391
|
+
* // Expect: [1] | [2]
|
|
2392
|
+
* type Example1 = TupleToUnionOfTuples<[1, 2]>
|
|
2393
|
+
* // Expect: never
|
|
2394
|
+
* type Example2 = TupleToUnionOfTuples<[]>
|
|
2395
|
+
* ```
|
|
2396
|
+
*/
|
|
2397
|
+
export type TupleToUnionOfTuples<T extends readonly unknown[]> =
|
|
2398
|
+
{ [K in keyof T]: [T[K]] }[number]
|
|
2399
|
+
|
|
2400
|
+
/**
|
|
2401
|
+
* Convert a tuple to a readonly tuple.
|
|
2402
|
+
*
|
|
2403
|
+
* @example
|
|
2404
|
+
* ```
|
|
2405
|
+
* // Expect: readonly [1, 2]
|
|
2406
|
+
* type Example1 = TupleToReadonly<[1, 2]>
|
|
2407
|
+
* // Expect: readonly []
|
|
2408
|
+
* type Example2 = TupleToReadonly<[]>
|
|
2409
|
+
* ```
|
|
2410
|
+
*/
|
|
2411
|
+
export type TupleToReadonly<T extends readonly unknown[]> = Readonly<T>
|
|
2412
|
+
|
|
2413
|
+
/**
|
|
2414
|
+
* Convert a tuple to a mutable tuple.
|
|
2415
|
+
*
|
|
2416
|
+
* @example
|
|
2417
|
+
* ```
|
|
2418
|
+
* // Expect: [1, 2]
|
|
2419
|
+
* type Example1 = TupleToMutable<readonly [1, 2]>
|
|
2420
|
+
* // Expect: []
|
|
2421
|
+
* type Example2 = TupleToMutable<readonly []>
|
|
2422
|
+
* ```
|
|
2423
|
+
*/
|
|
2424
|
+
export type TupleToMutable<T extends readonly unknown[]> = { -readonly [K in keyof T]: T[K] }
|