@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.
Files changed (91) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +30 -1
  3. package/dist/index.js +4 -2
  4. package/dist/index.js.map +22 -4
  5. package/package.json +3 -3
  6. package/scripts/build.ts +4 -4
  7. package/src/basic/README.md +144 -0
  8. package/src/basic/array.ts +872 -0
  9. package/src/basic/bigint.ts +114 -0
  10. package/src/basic/boolean.ts +180 -0
  11. package/src/basic/enhance.ts +10 -0
  12. package/src/basic/error.ts +51 -0
  13. package/src/basic/function.ts +453 -0
  14. package/src/basic/helper.ts +276 -0
  15. package/src/basic/index.ts +17 -0
  16. package/src/basic/is.ts +320 -0
  17. package/src/basic/number.ts +178 -0
  18. package/src/basic/object.ts +140 -0
  19. package/src/basic/promise.ts +464 -0
  20. package/src/basic/regexp.ts +7 -0
  21. package/src/basic/stream.ts +140 -0
  22. package/src/basic/string.ts +308 -0
  23. package/src/basic/symbol.ts +164 -0
  24. package/src/basic/temporal.ts +224 -0
  25. package/src/encoding/README.md +105 -0
  26. package/src/encoding/base64.ts +98 -0
  27. package/src/encoding/index.ts +1 -0
  28. package/src/index.ts +4 -0
  29. package/src/random/README.md +109 -0
  30. package/src/random/index.ts +1 -0
  31. package/src/random/uuid.ts +103 -0
  32. package/src/type/README.md +330 -0
  33. package/src/type/array.ts +5 -0
  34. package/src/type/boolean.ts +471 -0
  35. package/src/type/class.ts +419 -0
  36. package/src/type/function.ts +1519 -0
  37. package/src/type/helper.ts +135 -0
  38. package/src/type/index.ts +14 -0
  39. package/src/type/intersection.ts +93 -0
  40. package/src/type/is.ts +247 -0
  41. package/src/type/iteration.ts +233 -0
  42. package/src/type/number.ts +732 -0
  43. package/src/type/object.ts +788 -0
  44. package/src/type/path.ts +73 -0
  45. package/src/type/string.ts +1004 -0
  46. package/src/type/tuple.ts +2424 -0
  47. package/src/type/union.ts +108 -0
  48. package/tests/unit/basic/array.spec.ts +290 -0
  49. package/tests/unit/basic/bigint.spec.ts +50 -0
  50. package/tests/unit/basic/boolean.spec.ts +74 -0
  51. package/tests/unit/basic/error.spec.ts +32 -0
  52. package/tests/unit/basic/function.spec.ts +175 -0
  53. package/tests/unit/basic/helper.spec.ts +118 -0
  54. package/tests/unit/basic/number.spec.ts +74 -0
  55. package/tests/unit/basic/object.spec.ts +46 -0
  56. package/tests/unit/basic/promise.spec.ts +232 -0
  57. package/tests/unit/basic/regexp.spec.ts +11 -0
  58. package/tests/unit/basic/stream.spec.ts +120 -0
  59. package/tests/unit/basic/string.spec.ts +74 -0
  60. package/tests/unit/basic/symbol.spec.ts +72 -0
  61. package/tests/unit/basic/temporal.spec.ts +78 -0
  62. package/tests/unit/encoding/base64.spec.ts +40 -0
  63. package/tests/unit/random/uuid.spec.ts +37 -0
  64. package/dist/index.d.ts +0 -2
  65. package/dist/index.d.ts.map +0 -1
  66. package/dist/reactor/index.d.ts +0 -3
  67. package/dist/reactor/index.d.ts.map +0 -1
  68. package/dist/reactor/reactor-core/flags.d.ts +0 -99
  69. package/dist/reactor/reactor-core/flags.d.ts.map +0 -1
  70. package/dist/reactor/reactor-core/index.d.ts +0 -4
  71. package/dist/reactor/reactor-core/index.d.ts.map +0 -1
  72. package/dist/reactor/reactor-core/primitive.d.ts +0 -276
  73. package/dist/reactor/reactor-core/primitive.d.ts.map +0 -1
  74. package/dist/reactor/reactor-core/reactive-system.d.ts +0 -241
  75. package/dist/reactor/reactor-core/reactive-system.d.ts.map +0 -1
  76. package/dist/reactor/reactor-operators/branch.d.ts +0 -19
  77. package/dist/reactor/reactor-operators/branch.d.ts.map +0 -1
  78. package/dist/reactor/reactor-operators/convert.d.ts +0 -30
  79. package/dist/reactor/reactor-operators/convert.d.ts.map +0 -1
  80. package/dist/reactor/reactor-operators/create.d.ts +0 -26
  81. package/dist/reactor/reactor-operators/create.d.ts.map +0 -1
  82. package/dist/reactor/reactor-operators/filter.d.ts +0 -269
  83. package/dist/reactor/reactor-operators/filter.d.ts.map +0 -1
  84. package/dist/reactor/reactor-operators/index.d.ts +0 -8
  85. package/dist/reactor/reactor-operators/index.d.ts.map +0 -1
  86. package/dist/reactor/reactor-operators/join.d.ts +0 -48
  87. package/dist/reactor/reactor-operators/join.d.ts.map +0 -1
  88. package/dist/reactor/reactor-operators/map.d.ts +0 -165
  89. package/dist/reactor/reactor-operators/map.d.ts.map +0 -1
  90. package/dist/reactor/reactor-operators/utility.d.ts +0 -48
  91. package/dist/reactor/reactor-operators/utility.d.ts.map +0 -1
@@ -0,0 +1,1519 @@
1
+ // oxlint-disable explicit-module-boundary-types
2
+ // oxlint-disable no-explicit-any
3
+
4
+ import type { AnyFunction, AnyGeneratorFunction } from "./is.ts"
5
+ import type {
6
+ TupleAt, TupleHead, TupleLast, TuplePrev, TupleReverse, TupleTail
7
+ } from "./tuple.ts"
8
+
9
+ // ============================================================================
10
+ // Primitives
11
+ // ============================================================================
12
+
13
+ /**
14
+ * Type for a no-operation function.
15
+ *
16
+ * @example
17
+ * ```
18
+ * // Expect: () => void
19
+ * type Example1 = FunctionNoop
20
+ * ```
21
+ */
22
+ export type FunctionNoop = () => void
23
+
24
+ /**
25
+ * Type for an identity function.
26
+ *
27
+ * @example
28
+ * ```
29
+ * // Expect: (x: string) => string
30
+ * type Example1 = FunctionIdentity<string>
31
+ * // Expect: (x: number) => number
32
+ * type Example2 = FunctionIdentity<number>
33
+ * ```
34
+ */
35
+ export type FunctionIdentity<T> = (x: T) => T
36
+
37
+ /**
38
+ * Type for a constant function.
39
+ *
40
+ * @example
41
+ * ```
42
+ * // Expect: () => string
43
+ * type Example1 = FunctionConstant<string>
44
+ * // Expect: () => number
45
+ * type Example2 = FunctionConstant<number>
46
+ * ```
47
+ */
48
+ export type FunctionConstant<T> = () => T
49
+
50
+ /**
51
+ * Interface for type guard functions that use type predicates.
52
+ *
53
+ * Type predicates allow functions to narrow types at compile time.
54
+ *
55
+ * @see {@link https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates}
56
+ * @see {@link https://github.com/ts-essentials/ts-essentials#predicatetype}
57
+ *
58
+ * @example
59
+ * ```
60
+ * // Expect: valid predicate function
61
+ * const isString: FunctionPredicate<string> = (value: unknown): value is string => typeof value === 'string'
62
+ * // Expect: valid predicate function
63
+ * const isNumber: FunctionPredicate<number> = (value: unknown): value is number => typeof value === 'number'
64
+ * ```
65
+ */
66
+ export interface FunctionPredicate<Target = unknown> {
67
+ (target: Target, ..._: unknown[]): target is Target
68
+ (target: unknown, ..._: unknown[]): target is Target
69
+ }
70
+
71
+ /**
72
+ * Type for a mapper function.
73
+ *
74
+ * @example
75
+ * ```
76
+ * // Expect: (x: string) => number
77
+ * type Example1 = FunctionMapper<string, number>
78
+ * // Expect: (x: boolean) => string
79
+ * type Example2 = FunctionMapper<boolean, string>
80
+ * ```
81
+ */
82
+ export type FunctionMapper<T, U> = (x: T) => U
83
+
84
+ /**
85
+ * Type for a reducer function.
86
+ *
87
+ * @example
88
+ * ```
89
+ * // Expect: (acc: number, x: string) => number
90
+ * type Example1 = FunctionReducer<string, number>
91
+ * ```
92
+ */
93
+ export type FunctionReducer<T, Acc> = (acc: Acc, x: T) => Acc
94
+
95
+ /**
96
+ * Type for a comparator function.
97
+ *
98
+ * @example
99
+ * ```
100
+ * // Expect: (a: number, b: number) => number
101
+ * type Example1 = FunctionComparator<number>
102
+ * // Expect: (a: string, b: string) => number
103
+ * type Example2 = FunctionComparator<string>
104
+ * ```
105
+ */
106
+ export type FunctionComparator<T> = (a: T, b: T) => number
107
+
108
+ /**
109
+ * Type for a callback function.
110
+ *
111
+ * @example
112
+ * ```
113
+ * // Expect: (value: string) => void
114
+ * type Example1 = FunctionCallback<string>
115
+ * // Expect: (value: number) => void
116
+ * type Example2 = FunctionCallback<number>
117
+ * ```
118
+ */
119
+ export type FunctionCallback<T> = (value: T) => void
120
+
121
+ /**
122
+ * Type for an event handler function.
123
+ *
124
+ * @example
125
+ * ```
126
+ * type ClickEvent = { x: number; y: number }
127
+ * // Expect: (event: ClickEvent) => void
128
+ * type Example1 = FunctionEventHandler<ClickEvent>
129
+ * ```
130
+ */
131
+ export type FunctionEventHandler<E> = (event: E) => void
132
+
133
+ /**
134
+ * Type for an assertion function.
135
+ *
136
+ * @example
137
+ * ```
138
+ * // Expect: (value: unknown) => asserts value is string
139
+ * type Example1 = FunctionAssert<string>
140
+ * ```
141
+ */
142
+ export type FunctionAssert<T> = (value: unknown) => asserts value is T
143
+
144
+ /**
145
+ * Type for a decorator function that wraps another function.
146
+ *
147
+ * @example
148
+ * ```
149
+ * type Func = (a: number) => string
150
+ * // Expect: (fn: Func) => Func
151
+ * type Example1 = FunctionDecorator<Func>
152
+ * ```
153
+ */
154
+ export type FunctionDecorator<F extends AnyFunction> = (fn: F) => F
155
+
156
+ /**
157
+ * Type for a middleware function.
158
+ *
159
+ * @example
160
+ * ```
161
+ * type Context = { req: Request; res: Response }
162
+ * type Next = () => void
163
+ * // Expect: (ctx: Context, next: Next) => void
164
+ * type Example1 = FunctionMiddleware<Context, Next>
165
+ * ```
166
+ */
167
+ export type FunctionMiddleware<Context, Next extends AnyFunction> =
168
+ (ctx: Context, next: Next) => ReturnType<Next> | Promise<ReturnType<Next>>
169
+
170
+ /**
171
+ * Type for an interceptor function.
172
+ *
173
+ * @example
174
+ * ```
175
+ * type Value = string
176
+ * // Expect: (value: string) => string | Promise<string>
177
+ * type Example1 = FunctionInterceptor<Value>
178
+ * ```
179
+ */
180
+ export type FunctionInterceptor<T> = (value: T) => T | Promise<T>
181
+
182
+ /**
183
+ * Type for a memoized function (same signature but with cache).
184
+ *
185
+ * @example
186
+ * ```
187
+ * type Func = (a: number, b: string) => boolean
188
+ * // Expect: (a: number, b: string) => boolean
189
+ * type Example1 = FunctionMemoized<Func>
190
+ * ```
191
+ */
192
+ export type FunctionMemoized<F extends AnyFunction> = F
193
+
194
+ /**
195
+ * Type for a throttled function.
196
+ *
197
+ * @example
198
+ * ```
199
+ * type Func = (a: number) => void
200
+ * // Expect: (a: number) => void
201
+ * type Example1 = FunctionThrottled<Func>
202
+ * ```
203
+ */
204
+ export type FunctionThrottled<F extends AnyFunction> = F
205
+
206
+ /**
207
+ * Type for a debounced function.
208
+ *
209
+ * @example
210
+ * ```
211
+ * type Func = (a: number) => void
212
+ * // Expect: (a: number) => void
213
+ * type Example1 = FunctionDebounced<Func>
214
+ * ```
215
+ */
216
+ export type FunctionDebounced<F extends AnyFunction> = F
217
+
218
+ // ============================================================================
219
+ // Validation
220
+ // ============================================================================
221
+
222
+ /**
223
+ * Check if a function is synchronous (does not return Promise).
224
+ *
225
+ * @example
226
+ * ```
227
+ * type Func1 = () => string
228
+ * type Func2 = () => Promise<string>
229
+ * // Expect: true
230
+ * type Example1 = FunctionIsSync<Func1>
231
+ * // Expect: false
232
+ * type Example2 = FunctionIsSync<Func2>
233
+ * ```
234
+ */
235
+ export type FunctionIsSync<F> = F extends (...args: any[]) => Promise<any> ? false : (F extends AnyFunction ? true : false)
236
+
237
+ /**
238
+ * Check if a function is asynchronous (returns Promise).
239
+ *
240
+ * @example
241
+ * ```
242
+ * type Func1 = () => Promise<string>
243
+ * type Func2 = () => string
244
+ * // Expect: true
245
+ * type Example1 = FunctionIsAsync<Func1>
246
+ * // Expect: false
247
+ * type Example2 = FunctionIsAsync<Func2>
248
+ * ```
249
+ */
250
+ export type FunctionIsAsync<F> = F extends (...args: any[]) => Promise<any> ? true : false
251
+
252
+ /**
253
+ * Check if a function returns void.
254
+ *
255
+ * @example
256
+ * ```
257
+ * type Func1 = () => void
258
+ * type Func2 = () => string
259
+ * // Expect: true
260
+ * type Example1 = FunctionIsVoid<Func1>
261
+ * // Expect: false
262
+ * type Example2 = FunctionIsVoid<Func2>
263
+ * ```
264
+ */
265
+ export type FunctionIsVoid<F> = F extends (...args: any[]) => void ? true : false
266
+
267
+ /**
268
+ * Check if a function has variadic parameters (rest parameters).
269
+ *
270
+ * @example
271
+ * ```
272
+ * type Func1 = (...args: string[]) => void
273
+ * type Func2 = (a: string, b: number) => void
274
+ * // Expect: true
275
+ * type Example1 = FunctionIsVariadic<Func1>
276
+ * // Expect: false
277
+ * type Example2 = FunctionIsVariadic<Func2>
278
+ * ```
279
+ */
280
+ export type FunctionIsVariadic<F> = F extends (...args: infer P) => any
281
+ ? (P extends [...any[], ...infer Rest]
282
+ ? (Rest extends readonly any[] ? (number extends Rest['length'] ? true : false) : false)
283
+ : false)
284
+ : false
285
+
286
+ /**
287
+ * Check if a function has zero parameters.
288
+ *
289
+ * @example
290
+ * ```
291
+ * type Func1 = () => string
292
+ * type Func2 = (a: string) => string
293
+ * // Expect: true
294
+ * type Example1 = FunctionIsNullary<Func1>
295
+ * // Expect: false
296
+ * type Example2 = FunctionIsNullary<Func2>
297
+ * ```
298
+ */
299
+ export type FunctionIsNullary<F> = F extends () => any ? true : false
300
+
301
+ /**
302
+ * Check if a function has exactly one parameter.
303
+ *
304
+ * @example
305
+ * ```
306
+ * type Func1 = (a: string) => string
307
+ * type Func2 = (a: string, b: number) => string
308
+ * // Expect: true
309
+ * type Example1 = FunctionIsUnary<Func1>
310
+ * // Expect: false
311
+ * type Example2 = FunctionIsUnary<Func2>
312
+ * ```
313
+ */
314
+ export type FunctionIsUnary<F> = F extends (arg: any) => any ? true : false
315
+
316
+ /**
317
+ * Check if a function has exactly two parameters.
318
+ *
319
+ * @example
320
+ * ```
321
+ * type Func1 = (a: string, b: number) => string
322
+ * type Func2 = (a: string) => string
323
+ * // Expect: true
324
+ * type Example1 = FunctionIsBinary<Func1>
325
+ * // Expect: false
326
+ * type Example2 = FunctionIsBinary<Func2>
327
+ * ```
328
+ */
329
+ export type FunctionIsBinary<F> = F extends (arg1: any, arg2: any) => any ? true : false
330
+
331
+ /**
332
+ * Check if a function has exactly three parameters.
333
+ *
334
+ * @example
335
+ * ```
336
+ * type Func1 = (a: string, b: number, c: boolean) => string
337
+ * type Func2 = (a: string, b: number) => string
338
+ * // Expect: true
339
+ * type Example1 = FunctionIsTernary<Func1>
340
+ * // Expect: false
341
+ * type Example2 = FunctionIsTernary<Func2>
342
+ * ```
343
+ */
344
+ export type FunctionIsTernary<F> = F extends (arg1: any, arg2: any, arg3: any) => any ? true : false
345
+
346
+ /**
347
+ * Check if a function is a constructor function.
348
+ *
349
+ * @example
350
+ * ```
351
+ * class MyClass {}
352
+ * type Func = () => void
353
+ * // Expect: true
354
+ * type Example1 = FunctionIsConstructor<typeof MyClass>
355
+ * // Expect: false
356
+ * type Example2 = FunctionIsConstructor<Func>
357
+ * ```
358
+ */
359
+ export type FunctionIsConstructor<F> = F extends new (...args: any[]) => any ? true : false
360
+
361
+ /**
362
+ * Check if a function is a generator function.
363
+ *
364
+ * @example
365
+ * ```
366
+ * function* genFunc() { yield 1; yield 2; }
367
+ * type Func = () => void
368
+ * // Expect: true
369
+ * type Example1 = FunctionIsGenerator<typeof genFunc>
370
+ * // Expect: false
371
+ * type Example2 = FunctionIsGenerator<Func>
372
+ * ```
373
+ */
374
+ export type FunctionIsGenerator<F> = F extends (...args: any[]) => Generator<any, any, any> ? true : false
375
+
376
+ /**
377
+ * Check if a function is an async generator function.
378
+ *
379
+ * @example
380
+ * ```
381
+ * async function* asyncGenFunc() { yield 1; yield 2; }
382
+ * type Func = () => void
383
+ * // Expect: true
384
+ * type Example1 = FunctionIsAsyncGenerator<typeof asyncGenFunc>
385
+ * // Expect: false
386
+ * type Example2 = FunctionIsAsyncGenerator<Func>
387
+ * ```
388
+ */
389
+ export type FunctionIsAsyncGenerator<F> = F extends (...args: any[]) => AsyncGenerator<any, any, any> ? true : false
390
+
391
+ // ============================================================================
392
+ // Comparison
393
+ // ============================================================================
394
+
395
+ /**
396
+ * Check if two functions have equal parameter types.
397
+ *
398
+ * @example
399
+ * ```
400
+ * type F1 = (a: number, b: string) => void
401
+ * type F2 = (a: number, b: string) => boolean
402
+ * type F3 = (a: number) => void
403
+ * // Expect: true
404
+ * type Example1 = FunctionParametersEqual<F1, F2>
405
+ * // Expect: false
406
+ * type Example2 = FunctionParametersEqual<F1, F3>
407
+ * ```
408
+ */
409
+ export type FunctionParametersEqual<F1 extends AnyFunction, F2 extends AnyFunction> =
410
+ Parameters<F1> extends Parameters<F2>
411
+ ? (Parameters<F2> extends Parameters<F1> ? true : false)
412
+ : false
413
+
414
+ /**
415
+ * Check if two functions have equal return types.
416
+ *
417
+ * @example
418
+ * ```
419
+ * type F1 = (a: number) => string
420
+ * type F2 = (b: boolean) => string
421
+ * type F3 = (a: number) => number
422
+ * // Expect: true
423
+ * type Example1 = FunctionReturnEqual<F1, F2>
424
+ * // Expect: false
425
+ * type Example2 = FunctionReturnEqual<F1, F3>
426
+ * ```
427
+ */
428
+ export type FunctionReturnEqual<F1 extends AnyFunction, F2 extends AnyFunction> =
429
+ ReturnType<F1> extends ReturnType<F2>
430
+ ? (ReturnType<F2> extends ReturnType<F1> ? true : false)
431
+ : false
432
+
433
+ /**
434
+ * Check if two functions have equal signatures.
435
+ *
436
+ * @example
437
+ * ```
438
+ * type F1 = (a: number, b: string) => boolean
439
+ * type F2 = (a: number, b: string) => boolean
440
+ * type F3 = (a: number) => boolean
441
+ * // Expect: true
442
+ * type Example1 = FunctionSignatureEqual<F1, F2>
443
+ * // Expect: false
444
+ * type Example2 = FunctionSignatureEqual<F1, F3>
445
+ * ```
446
+ */
447
+ export type FunctionSignatureEqual<F1 extends AnyFunction, F2 extends AnyFunction> =
448
+ FunctionParametersEqual<F1, F2> extends true
449
+ ? FunctionReturnEqual<F1, F2>
450
+ : false
451
+
452
+ /**
453
+ * Check if function F1 is compatible with (assignable to) F2.
454
+ *
455
+ * @example
456
+ * ```
457
+ * type F1 = (a: number) => string
458
+ * type F2 = (a: number) => string | number
459
+ * // Expect: true
460
+ * type Example1 = FunctionCompatible<F1, F2>
461
+ * ```
462
+ */
463
+ export type FunctionCompatible<F1 extends AnyFunction, F2 extends AnyFunction> = F1 extends F2 ? true : false
464
+
465
+ // ============================================================================
466
+ // Query
467
+ // ============================================================================
468
+
469
+ /**
470
+ * Get the parameter length of a function type.
471
+ *
472
+ * @example
473
+ * ```
474
+ * type Func1 = (a: number, b: string) => string
475
+ * type Func2 = (...args: string[]) => string
476
+ * // Expect: 2
477
+ * type Example1 = FunctionLength<Func1>
478
+ * // Expect: number
479
+ * type Example2 = FunctionLength<Func2>
480
+ * // Expect: never
481
+ * type Example3 = FunctionLength<string>
482
+ * ```
483
+ */
484
+ export type FunctionLength<F extends AnyFunction> = F extends (...args: infer Parameters) => any ? Parameters["length"] : never
485
+
486
+ /**
487
+ * Get the arity (parameter count) of a function.
488
+ *
489
+ * @example
490
+ * ```
491
+ * type Func1 = (a: number, b: string) => string
492
+ * type Func2 = () => void
493
+ * // Expect: 2
494
+ * type Example1 = FunctionArity<Func1>
495
+ * // Expect: 0
496
+ * type Example2 = FunctionArity<Func2>
497
+ * ```
498
+ */
499
+ export type FunctionArity<F extends AnyFunction> = FunctionLength<F>
500
+
501
+ /**
502
+ * Extract the first parameter type of a function.
503
+ *
504
+ * @example
505
+ * ```
506
+ * type Func = (a: number, b: string) => void
507
+ * // Expect: number
508
+ * type Example1 = FunctionFirstParameter<Func>
509
+ * type NoParam = () => void
510
+ * // Expect: never
511
+ * type Example2 = FunctionFirstParameter<NoParam>
512
+ * ```
513
+ */
514
+ export type FunctionFirstParameter<F extends AnyFunction> = TupleHead<Parameters<F>>
515
+
516
+ /**
517
+ * Extract the last parameter type of a function.
518
+ *
519
+ * @example
520
+ * ```
521
+ * type Func = (a: number, b: string) => void
522
+ * // Expect: string
523
+ * type Example1 = FunctionLastParameter<Func>
524
+ * type Single = (a: number) => void
525
+ * // Expect: number
526
+ * type Example2 = FunctionLastParameter<Single>
527
+ * ```
528
+ */
529
+ export type FunctionLastParameter<F extends AnyFunction> = TupleLast<Parameters<F>>
530
+
531
+ /**
532
+ * Extract the parameter type at index N.
533
+ *
534
+ * @example
535
+ * ```
536
+ * type Func = (a: number, b: string, c: boolean) => void
537
+ * // Expect: number
538
+ * type Example1 = FunctionParameterAt<Func, 0>
539
+ * // Expect: string
540
+ * type Example2 = FunctionParameterAt<Func, 1>
541
+ * // Expect: boolean
542
+ * type Example3 = FunctionParameterAt<Func, 2>
543
+ * ```
544
+ */
545
+ export type FunctionParameterAt<F extends AnyFunction, N extends number> = TupleAt<Parameters<F>, N>
546
+
547
+ /**
548
+ * Extract rest parameters from a function (all parameters except the first).
549
+ *
550
+ * @example
551
+ * ```
552
+ * type Func = (a: number, b: string, c: boolean) => void
553
+ * // Expect: [string, boolean]
554
+ * type Example1 = FunctionRestParameters<Func>
555
+ * type Single = (a: number) => void
556
+ * // Expect: []
557
+ * type Example2 = FunctionRestParameters<Single>
558
+ * ```
559
+ */
560
+ export type FunctionRestParameters<F extends AnyFunction> = TupleTail<Parameters<F>>
561
+
562
+ /**
563
+ * Extract the predicated type from a type guard function.
564
+ *
565
+ * @see {@link https://github.com/ts-essentials/ts-essentials#predicatetype}
566
+ *
567
+ * @example
568
+ * ```
569
+ * const isString = (value: unknown): value is string => typeof value === 'string'
570
+ * const isNumber = (value: unknown): value is number => typeof value === 'number'
571
+ * // Expect: string
572
+ * type Example1 = PredicateTypeOf<typeof isString>
573
+ * // Expect: number
574
+ * type Example2 = PredicateTypeOf<typeof isNumber>
575
+ * ```
576
+ */
577
+ export type FunctionPredicateType<F extends FunctionPredicate> =
578
+ F extends (target: unknown, ...rest: any[]) => target is infer P ? P : never
579
+
580
+ /**
581
+ * Extract the yield type from a generator function.
582
+ *
583
+ * @example
584
+ * ```
585
+ * type GenFunc = () => Generator<string, number, boolean>
586
+ * // Expect: string
587
+ * type Example1 = FunctionGeneratorYield<GenFunc>
588
+ * ```
589
+ */
590
+ export type FunctionGeneratorYield<F extends AnyGeneratorFunction> =
591
+ ReturnType<F> extends Generator<infer Y, any, any> ? Y : never
592
+
593
+ /**
594
+ * Extract the return type from a generator function.
595
+ *
596
+ * @example
597
+ * ```
598
+ * type GenFunc = () => Generator<string, number, boolean>
599
+ * // Expect: number
600
+ * type Example1 = FunctionGeneratorReturn<GenFunc>
601
+ * ```
602
+ */
603
+ export type FunctionGeneratorReturn<F extends AnyGeneratorFunction> =
604
+ ReturnType<F> extends Generator<any, infer R, any> ? R : never
605
+
606
+ /**
607
+ * Extract the next parameter type from a generator function.
608
+ *
609
+ * @example
610
+ * ```
611
+ * type GenFunc = () => Generator<string, number, boolean>
612
+ * // Expect: boolean
613
+ * type Example1 = FunctionGeneratorNext<GenFunc>
614
+ * ```
615
+ */
616
+ export type FunctionGeneratorNext<F extends AnyGeneratorFunction> =
617
+ ReturnType<F> extends Generator<any, any, infer N> ? N : never
618
+
619
+ // ============================================================================
620
+ // Manipulation (this)
621
+ // ============================================================================
622
+
623
+ /**
624
+ * Extract the this type from a function.
625
+ *
626
+ * @example
627
+ * ```
628
+ * type Func = (this: { x: number }, a: string) => void
629
+ * // Expect: { x: number }
630
+ * type Example1 = FunctionThisType<Func>
631
+ * type NoThis = (a: string) => void
632
+ * // Expect: unknown
633
+ * type Example2 = FunctionThisType<NoThis>
634
+ * ```
635
+ */
636
+ export type FunctionThisType<F> = F extends (this: infer This, ...args: any[]) => any ? This : unknown
637
+
638
+ /**
639
+ * Bind this type to a function.
640
+ *
641
+ * @example
642
+ * ```
643
+ * type Func = (a: string) => void
644
+ * // Expect: (this: { x: number }, a: string) => void
645
+ * type Example1 = FunctionBindThis<Func, { x: number }>
646
+ * ```
647
+ */
648
+ export type FunctionBindThis<F extends AnyFunction, This> =
649
+ F extends (...args: infer P) => infer R
650
+ ? (this: This, ...args: P) => R
651
+ : never
652
+
653
+ /**
654
+ * Remove this parameter from a function.
655
+ *
656
+ * @example
657
+ * ```
658
+ * type Func = (this: { x: number }, a: string, b: number) => void
659
+ * // Expect: (a: string, b: number) => void
660
+ * type Example1 = FunctionOmitThis<Func>
661
+ * type NoThis = (a: string) => void
662
+ * // Expect: (a: string) => void
663
+ * type Example2 = FunctionOmitThis<NoThis>
664
+ * ```
665
+ */
666
+ export type FunctionOmitThis<F> =
667
+ F extends (this: any, ...args: infer P) => infer R
668
+ ? (...args: P) => R
669
+ : F
670
+
671
+ /**
672
+ * Convert function to arrow function type (removes this).
673
+ *
674
+ * @example
675
+ * ```
676
+ * type Func = (this: { x: number }, a: string) => void
677
+ * // Expect: (a: string) => void
678
+ * type Example1 = FunctionToArrow<Func>
679
+ * ```
680
+ */
681
+ export type FunctionToArrow<F> = FunctionOmitThis<F>
682
+
683
+ /**
684
+ * Add this parameter to a function that doesn't have one.
685
+ *
686
+ * @example
687
+ * ```
688
+ * type Func = (a: string) => void
689
+ * // Expect: (this: { x: number }, a: string) => void
690
+ * type Example1 = FunctionWithThis<Func, { x: number }>
691
+ * ```
692
+ */
693
+ export type FunctionWithThis<F extends AnyFunction, This> = FunctionBindThis<F, This>
694
+
695
+ // ============================================================================
696
+ // Manipulation (whole)
697
+ // ============================================================================
698
+
699
+ /**
700
+ * Convert a function type to return a Promise of its original return type.
701
+ *
702
+ * @example
703
+ * ```
704
+ * type Func = (a: number, b: string) => string
705
+ * // Expect: (a: number, b: string) => Promise<string>
706
+ * type Example1 = FunctionPromisify<Func>
707
+ * type VoidFunc = () => void
708
+ * // Expect: () => Promise<void>
709
+ * type Example2 = FunctionPromisify<VoidFunc>
710
+ * ```
711
+ */
712
+ export type FunctionPromisify<Target extends AnyFunction> = (...args: Parameters<Target>) => Promise<ReturnType<Target>>
713
+
714
+ /**
715
+ * Alias for FunctionPromisify.
716
+ *
717
+ * @example
718
+ * ```
719
+ * type Func = (a: number) => string
720
+ * // Expect: (a: number) => Promise<string>
721
+ * type Example1 = FunctionAsyncify<Func>
722
+ * ```
723
+ */
724
+ export type FunctionAsyncify<F extends AnyFunction> = FunctionPromisify<F>
725
+
726
+ /**
727
+ * Convert function parameters to Promises and return Promise of result.
728
+ *
729
+ * @example
730
+ * ```
731
+ * type Func = (a: number, b: string) => boolean
732
+ * // Expect: (a: Promise<number>, b: Promise<string>) => Promise<boolean>
733
+ * type Example1 = FunctionPromisifyAll<Func>
734
+ * ```
735
+ */
736
+ export type FunctionPromisifyAll<F extends AnyFunction> =
737
+ Parameters<F> extends [infer First, ...infer Rest]
738
+ ? (
739
+ Rest extends []
740
+ ? (a: Promise<First>) => Promise<ReturnType<F>>
741
+ : (a: Promise<First>, ...args: { [K in keyof Rest]: Promise<Rest[K]> }) => Promise<ReturnType<F>>
742
+ )
743
+ : F
744
+
745
+ /**
746
+ * Unwrap Promise return type to make function synchronous.
747
+ *
748
+ * @example
749
+ * ```
750
+ * type AsyncFunc = () => Promise<string>
751
+ * // Expect: () => string
752
+ * type Example1 = FunctionSyncify<AsyncFunc>
753
+ * type SyncFunc = () => string
754
+ * // Expect: () => string
755
+ * type Example2 = FunctionSyncify<SyncFunc>
756
+ * ```
757
+ */
758
+ export type FunctionSyncify<F extends AnyFunction> =
759
+ ReturnType<F> extends Promise<infer T> ? (...args: Parameters<F>) => T : F
760
+
761
+ /**
762
+ * Convert function return type to void.
763
+ *
764
+ * @example
765
+ * ```
766
+ * type Func = (a: number) => string
767
+ * // Expect: (a: number) => void
768
+ * type Example1 = FunctionVoidify<Func>
769
+ * ```
770
+ */
771
+ export type FunctionVoidify<F extends AnyFunction> = (...args: Parameters<F>) => void
772
+
773
+ /**
774
+ * Convert function return type to null.
775
+ *
776
+ * @example
777
+ * ```
778
+ * type Func = (a: number) => string
779
+ * // Expect: (a: number) => null
780
+ * type Example1 = FunctionNullify<Func>
781
+ * ```
782
+ */
783
+ export type FunctionNullify<F extends AnyFunction> = (...args: Parameters<F>) => null
784
+
785
+ /**
786
+ * Make all function parameters optional.
787
+ *
788
+ * @example
789
+ * ```
790
+ * type Func = (a: number, b: string) => void
791
+ * // Expect: (a?: number, b?: string) => void
792
+ * type Example1 = FunctionOptionalify<Func>
793
+ * ```
794
+ */
795
+ export type FunctionOptionalify<F extends AnyFunction> = (...args: Partial<Parameters<F>>) => ReturnType<F>
796
+
797
+ /**
798
+ * Make all function parameters required.
799
+ *
800
+ * @example
801
+ * ```
802
+ * type Func = (a?: number, b?: string) => void
803
+ * // Expect: (a: number, b: string) => void
804
+ * type Example1 = FunctionRequiredify<Func>
805
+ * ```
806
+ */
807
+ export type FunctionRequiredify<F extends AnyFunction> = (...args: Required<Parameters<F>>) => ReturnType<F>
808
+
809
+ /**
810
+ * Make all function parameters readonly.
811
+ *
812
+ * @example
813
+ * ```
814
+ * type Func = (a: number[], b: { x: number }) => void
815
+ * // Expect: (a: readonly number[], b: Readonly<{ x: number }>) => void
816
+ * type Example1 = FunctionReadonly<Func>
817
+ * ```
818
+ */
819
+ export type FunctionReadonly<F extends AnyFunction> = (...args: Readonly<Parameters<F>>) => ReturnType<F>
820
+
821
+ // ============================================================================
822
+ // Manipulation (parameters)
823
+ // ============================================================================
824
+
825
+ /**
826
+ * Check if a function has optional parameters.
827
+ *
828
+ * @example
829
+ * ```
830
+ * type Func1 = (a: number, b?: string) => void
831
+ * type Func2 = (a: number, b: string) => void
832
+ * // Expect: true
833
+ * type Example1 = FunctionHasOptionalParameters<Func1>
834
+ * // Expect: false
835
+ * type Example2 = FunctionHasOptionalParameters<Func2>
836
+ * ```
837
+ */
838
+ export type FunctionHasOptionalParameters<F extends AnyFunction> =
839
+ Parameters<F> extends Partial<Parameters<F>>
840
+ ? (Partial<Parameters<F>> extends Parameters<F> ? false : true)
841
+ : false
842
+
843
+ /**
844
+ * Reverse the order of function parameters.
845
+ *
846
+ * @example
847
+ * ```
848
+ * type Func = (a: string, b: number, c: boolean) => void
849
+ * // Expect: (c: boolean, b: number, a: string) => void
850
+ * type Example1 = FunctionReverseParameters<Func>
851
+ * ```
852
+ */
853
+ export type FunctionReverseParameters<F extends AnyFunction> = (...args: TupleReverse<Parameters<F>>) => ReturnType<F>
854
+
855
+ type InternalInsertParameter<
856
+ Params extends readonly any[],
857
+ N extends number,
858
+ T,
859
+ Count extends readonly any[] = [],
860
+ Acc extends readonly any[] = []
861
+ > = Count['length'] extends N
862
+ ? [...Acc, T, ...Params]
863
+ : (Params extends [infer First, ...infer Rest]
864
+ ? InternalInsertParameter<Rest, N, T, [...Count, any], [...Acc, First]>
865
+ : [...Acc, T])
866
+ /**
867
+ * Insert a parameter at index N in the function parameter list.
868
+ *
869
+ * @example
870
+ * ```
871
+ * type Func = (a: string, c: boolean) => void
872
+ * // Expect: (a: string, b: number, c: boolean) => void
873
+ * type Example1 = FunctionInsertParameter<Func, 1, number>
874
+ * ```
875
+ */
876
+ export type FunctionInsertParameter<F extends AnyFunction, N extends number, T> =
877
+ (...args: InternalInsertParameter<Parameters<F>, N, T>) => ReturnType<F>
878
+
879
+ /**
880
+ * Prepend a parameter to the function parameter list.
881
+ *
882
+ * @example
883
+ * ```
884
+ * type Func = (b: string) => void
885
+ * // Expect: (a: number, b: string) => void
886
+ * type Example1 = FunctionPrependParameter<Func, number>
887
+ * ```
888
+ */
889
+ export type FunctionPrependParameter<F extends AnyFunction, T> = (arg: T, ...args: Parameters<F>) => ReturnType<F>
890
+
891
+ /**
892
+ * Append a parameter to the function parameter list.
893
+ *
894
+ * @example
895
+ * ```
896
+ * type Func = (a: string) => void
897
+ * // Expect: (a: string, b: number) => void
898
+ * type Example1 = FunctionAppendParameter<Func, number>
899
+ * ```
900
+ */
901
+ export type FunctionAppendParameter<F extends AnyFunction, T> = (...args: [...Parameters<F>, T]) => ReturnType<F>
902
+
903
+ type InternalRemoveParameter<
904
+ Params extends readonly any[],
905
+ N extends number,
906
+ Count extends readonly any[] = [],
907
+ Acc extends readonly any[] = []
908
+ > = Params extends [infer First, ...infer Rest]
909
+ ? (Count['length'] extends N
910
+ ? [...Acc, ...Rest]
911
+ : InternalRemoveParameter<Rest, N, [...Count, any], [...Acc, First]>)
912
+ : Acc
913
+ /**
914
+ * Remove the parameter at index N from the function parameter list.
915
+ *
916
+ * @example
917
+ * ```
918
+ * type Func = (a: string, b: number, c: boolean) => void
919
+ * // Expect: (a: string, c: boolean) => void
920
+ * type Example1 = FunctionRemoveParameter<Func, 1>
921
+ * ```
922
+ */
923
+ export type FunctionRemoveParameter<F extends AnyFunction, N extends number> =
924
+ (...args: InternalRemoveParameter<Parameters<F>, N>) => ReturnType<F>
925
+
926
+ /**
927
+ * Remove the first parameter from the function parameter list.
928
+ *
929
+ * @example
930
+ * ```
931
+ * type Func = (a: string, b: number) => void
932
+ * // Expect: (b: number) => void
933
+ * type Example1 = FunctionRemoveFirstParameter<Func>
934
+ * ```
935
+ */
936
+ export type FunctionRemoveFirstParameter<F extends AnyFunction> = (...args: TupleTail<Parameters<F>>) => ReturnType<F>
937
+
938
+ /**
939
+ * Remove the last parameter from the function parameter list.
940
+ *
941
+ * @example
942
+ * ```
943
+ * type Func = (a: string, b: number) => void
944
+ * // Expect: (a: string) => void
945
+ * type Example1 = FunctionRemoveLastParameter<Func>
946
+ * ```
947
+ */
948
+ export type FunctionRemoveLastParameter<F extends AnyFunction> =
949
+ Parameters<F> extends [...infer Init, any]
950
+ ? (...args: Init) => ReturnType<F>
951
+ : () => ReturnType<F>
952
+
953
+ type InternalReplaceParameter<
954
+ Params extends readonly any[],
955
+ N extends number,
956
+ T,
957
+ Count extends readonly any[] = [],
958
+ Acc extends readonly any[] = []
959
+ > = Params extends [infer First, ...infer Rest]
960
+ ? (Count['length'] extends N
961
+ ? [...Acc, T, ...Rest]
962
+ : InternalReplaceParameter<Rest, N, T, [...Count, any], [...Acc, First]>)
963
+ : Acc
964
+ /**
965
+ * Replace the parameter at index N with a new type.
966
+ *
967
+ * @example
968
+ * ```
969
+ * type Func = (a: string, b: number, c: boolean) => void
970
+ * // Expect: (a: string, b: Date, c: boolean) => void
971
+ * type Example1 = FunctionReplaceParameter<Func, 1, Date>
972
+ * ```
973
+ */
974
+ export type FunctionReplaceParameter<F extends AnyFunction, N extends number, T> =
975
+ (...args: InternalReplaceParameter<Parameters<F>, N, T>) => ReturnType<F>
976
+
977
+ /**
978
+ * Narrow parameter type to a more specific type.
979
+ *
980
+ * @example
981
+ * ```
982
+ * type Func = (a: any) => void
983
+ * // Expect: (a: number) => void
984
+ * type Example1 = FunctionNarrowParameter<Func, 0, number>
985
+ * ```
986
+ */
987
+ export type FunctionNarrowParameter<F extends AnyFunction, Index extends number, Narrow> =
988
+ FunctionReplaceParameter<F, Index, Narrow>
989
+
990
+ /**
991
+ * Widen parameter type to a more general type.
992
+ *
993
+ * @example
994
+ * ```
995
+ * type Func = (a: number) => void
996
+ * // Expect: (a: any) => void
997
+ * type Example1 = FunctionWidenParameter<Func, 0, any>
998
+ * ```
999
+ */
1000
+ export type FunctionWidenParameter<F extends AnyFunction, Index extends number, Widen> =
1001
+ FunctionReplaceParameter<F, Index, Widen>
1002
+
1003
+ type InternalSliceParameters<
1004
+ Params extends readonly any[],
1005
+ Start extends number,
1006
+ End extends number | undefined,
1007
+ Count extends readonly any[] = [],
1008
+ Acc extends readonly any[] = []
1009
+ > = Params extends [infer First, ...infer Rest]
1010
+ ? (Count['length'] extends End
1011
+ ? Acc
1012
+ : (Start extends Count['length']
1013
+ ? InternalSliceParameters<Rest, Start, End, [...Count, any], [...Acc, First]>
1014
+ : (Count['length'] extends Start
1015
+ ? InternalSliceParameters<Rest, Start, End, [...Count, any], [First]>
1016
+ : InternalSliceParameters<Rest, Start, End, [...Count, any], Acc>)))
1017
+ : Acc
1018
+ /**
1019
+ * Slice parameters from Start to End (like Array.slice).
1020
+ *
1021
+ * @example
1022
+ * ```
1023
+ * type Func = (a: number, b: string, c: boolean, d: symbol) => void
1024
+ * // Expect: (b: string, c: boolean) => void
1025
+ * type Example1 = FunctionSliceParameters<Func, 1, 3>
1026
+ * // Expect: (b: string, c: boolean, d: symbol) => void
1027
+ * type Example2 = FunctionSliceParameters<Func, 1, undefined>
1028
+ * // Expect: (a: number, b: string) => void
1029
+ * type Example3 = FunctionSliceParameters<Func, 0, 2>
1030
+ * ```
1031
+ */
1032
+ export type FunctionSliceParameters<
1033
+ F extends AnyFunction,
1034
+ Start extends number,
1035
+ End extends number | undefined = undefined
1036
+ > = (...args: InternalSliceParameters<Parameters<F>, Start, End>) => ReturnType<F>
1037
+
1038
+ /**
1039
+ * Pick specific parameters by index.
1040
+ *
1041
+ * @example
1042
+ * ```
1043
+ * type Func = (a: number, b: string, c: boolean) => void
1044
+ * // Expect: (a: number, c: boolean) => void
1045
+ * type Example1 = FunctionPickParameters<Func, 0 | 2>
1046
+ * ```
1047
+ */
1048
+ export type FunctionPickParameters<F extends AnyFunction, Indices extends number> =
1049
+ Parameters<F> extends [...infer P]
1050
+ ? (...args: Array<{ [K in Indices]: K extends keyof P ? P[K] : never }[Indices]>) => ReturnType<F>
1051
+ : never
1052
+
1053
+ /**
1054
+ * Omit specific parameters by index.
1055
+ *
1056
+ * @example
1057
+ * ```
1058
+ * type Func = (a: number, b: string, c: boolean) => void
1059
+ * // Expect: (b: string) => void
1060
+ * type Example1 = FunctionOmitParameters<Func, 0 | 2>
1061
+ * ```
1062
+ */
1063
+ export type FunctionOmitParameters<F extends AnyFunction, Indices extends number> =
1064
+ Parameters<F> extends [...infer P]
1065
+ ? (...args: Array<{ [K in keyof P]: K extends `${Indices}` ? never : P[K] }[number]>) => ReturnType<F>
1066
+ : never
1067
+
1068
+ /**
1069
+ * Flatten nested tuple parameters into a single parameter list.
1070
+ *
1071
+ * @example
1072
+ * ```
1073
+ * type Func = (a: [number, string], b: [boolean]) => void
1074
+ * // Expect: (a: number, b: string, c: boolean) => void
1075
+ * type Example1 = FunctionFlattenParameters<Func>
1076
+ * ```
1077
+ */
1078
+ export type FunctionFlattenParameters<F extends AnyFunction> =
1079
+ Parameters<F> extends [infer A, ...infer Rest]
1080
+ ? (A extends readonly any[]
1081
+ ? (...args: [...A, ...Rest]) => ReturnType<F>
1082
+ : F)
1083
+ : F
1084
+
1085
+ /**
1086
+ * Group parameters into a tuple.
1087
+ *
1088
+ * @example
1089
+ * ```
1090
+ * type Func = (a: number, b: string, c: boolean) => void
1091
+ * // Expect: (args: [number, string, boolean]) => void
1092
+ * type Example1 = FunctionGroupParameters<Func>
1093
+ * ```
1094
+ */
1095
+ export type FunctionGroupParameters<F extends AnyFunction> =
1096
+ (args: Parameters<F>) => ReturnType<F>
1097
+
1098
+ /**
1099
+ * Spread grouped parameters back to individual parameters.
1100
+ *
1101
+ * @example
1102
+ * ```
1103
+ * type Func = (args: [number, string, boolean]) => void
1104
+ * // Expect: (a: number, b: string, c: boolean) => void
1105
+ * type Example1 = FunctionSpreadParameters<Func>
1106
+ * ```
1107
+ */
1108
+ export type FunctionSpreadParameters<F extends AnyFunction> =
1109
+ Parameters<F> extends [infer A]
1110
+ ? (A extends readonly any[]
1111
+ ? (...args: A) => ReturnType<F>
1112
+ : F)
1113
+ : F
1114
+
1115
+ /**
1116
+ * Distribute function over union parameters.
1117
+ *
1118
+ * @example
1119
+ * ```
1120
+ * type Func = (a: number | string) => void
1121
+ * // Expect: ((a: number) => void) | ((a: string) => void)
1122
+ * type Example1 = FunctionDistributeParameters<Func>
1123
+ * ```
1124
+ */
1125
+ export type FunctionDistributeParameters<F extends AnyFunction> =
1126
+ Parameters<F> extends [infer First, ...infer Rest]
1127
+ ? (
1128
+ First extends any
1129
+ ? (arg: First, ...rest: Rest) => ReturnType<F>
1130
+ : never
1131
+ )
1132
+ : F
1133
+
1134
+ // ============================================================================
1135
+ // Manipulation (return)
1136
+ // ============================================================================
1137
+
1138
+ /**
1139
+ * Map the return type of a function through a type transformation.
1140
+ *
1141
+ * @example
1142
+ * ```
1143
+ * type Func = () => string
1144
+ * // Expect: () => string[]
1145
+ * type Example1 = FunctionMapReturn<Func, Array<string>>
1146
+ * ```
1147
+ */
1148
+ export type FunctionMapReturn<F extends AnyFunction, R> = (...args: Parameters<F>) => R
1149
+
1150
+ /**
1151
+ * Flatten nested Promise return types.
1152
+ *
1153
+ * @example
1154
+ * ```
1155
+ * type Func = () => Promise<Promise<string>>
1156
+ * // Expect: () => Promise<string>
1157
+ * type Example1 = FunctionFlatReturn<Func>
1158
+ * ```
1159
+ */
1160
+ export type FunctionFlatReturn<F extends AnyFunction> =
1161
+ ReturnType<F> extends Promise<infer Inner>
1162
+ ? (Inner extends Promise<any>
1163
+ ? (...args: Parameters<F>) => Inner
1164
+ : F)
1165
+ : F
1166
+
1167
+ /**
1168
+ * Unwrap the return type (Promise or Array).
1169
+ *
1170
+ * @example
1171
+ * ```
1172
+ * type AsyncFunc = () => Promise<string>
1173
+ * type ArrayFunc = () => string[]
1174
+ * // Expect: () => string
1175
+ * type Example1 = FunctionUnwrapReturn<AsyncFunc>
1176
+ * // Expect: () => string
1177
+ * type Example2 = FunctionUnwrapReturn<ArrayFunc>
1178
+ * ```
1179
+ */
1180
+ export type FunctionUnwrapReturn<F extends AnyFunction> =
1181
+ ReturnType<F> extends Promise<infer T>
1182
+ ? (...args: Parameters<F>) => T
1183
+ : (
1184
+ ReturnType<F> extends Array<infer U>
1185
+ ? (...args: Parameters<F>) => U
1186
+ : F
1187
+ )
1188
+
1189
+ /**
1190
+ * Wrap the return type with a wrapper type.
1191
+ *
1192
+ * @example
1193
+ * ```
1194
+ * type Func = () => string
1195
+ * // Expect: () => Promise<string>
1196
+ * type Example1 = FunctionWrapReturn<Func, Promise<string>>
1197
+ * // Expect: () => Array<string>
1198
+ * type Example2 = FunctionWrapReturn<Func, Array<string>>
1199
+ * ```
1200
+ */
1201
+ export type FunctionWrapReturn<F extends AnyFunction, Wrapper> = (...args: Parameters<F>) => Wrapper
1202
+
1203
+ /**
1204
+ * Convert return type to an array.
1205
+ *
1206
+ * @example
1207
+ * ```
1208
+ * type Func = () => string
1209
+ * // Expect: () => string[]
1210
+ * type Example1 = FunctionReturnArray<Func>
1211
+ * type VoidFunc = () => void
1212
+ * // Expect: () => void[]
1213
+ * type Example2 = FunctionReturnArray<VoidFunc>
1214
+ * ```
1215
+ */
1216
+ export type FunctionReturnArray<F extends AnyFunction> = (...args: Parameters<F>) => Array<ReturnType<F>>
1217
+
1218
+ /**
1219
+ * Convert return type to a tuple with one element.
1220
+ *
1221
+ * @example
1222
+ * ```
1223
+ * type Func = () => string
1224
+ * // Expect: () => [string]
1225
+ * type Example1 = FunctionReturnTuple<Func>
1226
+ * ```
1227
+ */
1228
+ export type FunctionReturnTuple<F extends AnyFunction> = (...args: Parameters<F>) => [ReturnType<F>]
1229
+
1230
+ /**
1231
+ * Make return type nullable (add null | undefined).
1232
+ *
1233
+ * @example
1234
+ * ```
1235
+ * type Func = () => string
1236
+ * // Expect: () => string | null | undefined
1237
+ * type Example1 = FunctionReturnNullable<Func>
1238
+ * ```
1239
+ */
1240
+ export type FunctionReturnNullable<F extends AnyFunction> =
1241
+ (...args: Parameters<F>) => ReturnType<F> | null | undefined
1242
+
1243
+ /**
1244
+ * Remove null and undefined from return type.
1245
+ *
1246
+ * @example
1247
+ * ```
1248
+ * type Func = () => string | null | undefined
1249
+ * // Expect: () => string
1250
+ * type Example1 = FunctionReturnNonNullable<Func>
1251
+ * type NoNull = () => string
1252
+ * // Expect: () => string
1253
+ * type Example2 = FunctionReturnNonNullable<NoNull>
1254
+ * ```
1255
+ */
1256
+ export type FunctionReturnNonNullable<F extends AnyFunction> =
1257
+ (...args: Parameters<F>) => NonNullable<ReturnType<F>>
1258
+
1259
+ /**
1260
+ * Extract specific type from union return type.
1261
+ *
1262
+ * @example
1263
+ * ```
1264
+ * type Func = () => string | number | boolean
1265
+ * // Expect: () => string
1266
+ * type Example1 = FunctionReturnExtract<Func, string>
1267
+ * // Expect: () => string | number
1268
+ * type Example2 = FunctionReturnExtract<Func, string | number>
1269
+ * ```
1270
+ */
1271
+ export type FunctionReturnExtract<F extends AnyFunction, U> =
1272
+ (...args: Parameters<F>) => Extract<ReturnType<F>, U>
1273
+
1274
+ /**
1275
+ * Exclude specific type from union return type.
1276
+ *
1277
+ * @example
1278
+ * ```
1279
+ * type Func = () => string | number | boolean
1280
+ * // Expect: () => number | boolean
1281
+ * type Example1 = FunctionReturnExclude<Func, string>
1282
+ * // Expect: () => boolean
1283
+ * type Example2 = FunctionReturnExclude<Func, string | number>
1284
+ * ```
1285
+ */
1286
+ export type FunctionReturnExclude<F extends AnyFunction, U> =
1287
+ (...args: Parameters<F>) => Exclude<ReturnType<F>, U>
1288
+
1289
+ // ============================================================================
1290
+ // Manipulation (functional)
1291
+ // ============================================================================
1292
+
1293
+ /**
1294
+ * Compose two functions (f1(f2(x))).
1295
+ *
1296
+ * @example
1297
+ * ```
1298
+ * type F1 = (x: number) => string
1299
+ * type F2 = (x: boolean) => number
1300
+ * // Expect: (x: boolean) => string
1301
+ * type Example1 = FunctionCompose<F1, F2>
1302
+ * ```
1303
+ */
1304
+ export type FunctionCompose<F1 extends AnyFunction, F2 extends AnyFunction> =
1305
+ ReturnType<F2> extends Parameters<F1>[0]
1306
+ ? (...args: Parameters<F2>) => ReturnType<F1>
1307
+ : never
1308
+
1309
+ /**
1310
+ * Pipe two functions (f2(f1(x))).
1311
+ *
1312
+ * @example
1313
+ * ```
1314
+ * type F1 = (x: boolean) => number
1315
+ * type F2 = (x: number) => string
1316
+ * // Expect: (x: boolean) => string
1317
+ * type Example1 = FunctionPipe<F1, F2>
1318
+ * ```
1319
+ */
1320
+ export type FunctionPipe<F1 extends AnyFunction, F2 extends AnyFunction> = FunctionCompose<F2, F1>
1321
+
1322
+ interface FunctionComposeError<Fn, Expected, Got> {
1323
+ __compose_error__: true
1324
+ function: Fn
1325
+ expected: Expected
1326
+ got: Got
1327
+ }
1328
+ type FunctionComposeChain<
1329
+ Fns extends AnyFunction[],
1330
+ CurrentReturn,
1331
+ InitialArgs extends any[]
1332
+ > =
1333
+ Fns extends []
1334
+ ? (...args: InitialArgs) => CurrentReturn
1335
+ : (
1336
+ TupleLast<Fns> extends (arg: infer A) => infer R
1337
+ ? (
1338
+ [CurrentReturn] extends [A]
1339
+ ? FunctionComposeChain<TuplePrev<Fns>, R, InitialArgs>
1340
+ : FunctionComposeError<TupleLast<Fns>, A, CurrentReturn>
1341
+ )
1342
+ : never
1343
+ )
1344
+ /**
1345
+ * Compose multiple functions from right to left.
1346
+ *
1347
+ * @example
1348
+ * ```
1349
+ * type F1 = (x: string) => number
1350
+ * type F2 = (x: boolean) => string
1351
+ * type F3 = (x: symbol) => boolean
1352
+ * // Expect: (x: symbol) => number
1353
+ * type Example1 = FunctionComposeAll<[F1, F2, F3]>
1354
+ * ```
1355
+ */
1356
+ export type FunctionComposeAll<Fns extends AnyFunction[]> =
1357
+ Fns extends [AnyFunction]
1358
+ ? Fns[0]
1359
+ : (
1360
+ TupleLast<Fns> extends (...args: infer Args) => infer R
1361
+ ? FunctionComposeChain<TuplePrev<Fns>, R, Args>
1362
+ : never
1363
+ )
1364
+
1365
+ /**
1366
+ * Pipe multiple functions from left to right.
1367
+ *
1368
+ * @example
1369
+ * ```
1370
+ * type F1 = (x: symbol) => boolean
1371
+ * type F2 = (x: boolean) => string
1372
+ * type F3 = (x: string) => number
1373
+ * // Expect: (x: symbol) => number
1374
+ * type Example1 = FunctionPipeAll<[F1, F2, F3]>
1375
+ * ```
1376
+ */
1377
+ export type FunctionPipeAll<Fns extends readonly AnyFunction[]> =
1378
+ FunctionComposeAll<TupleReverse<Fns>>
1379
+
1380
+ /**
1381
+ * Create a union of function types.
1382
+ *
1383
+ * @example
1384
+ * ```
1385
+ * type F1 = (a: number) => string
1386
+ * type F2 = (b: boolean) => number
1387
+ * // Expect: F1 | F2
1388
+ * type Example1 = FunctionUnion<F1, F2>
1389
+ * ```
1390
+ */
1391
+ export type FunctionUnion<F1 extends AnyFunction, F2 extends AnyFunction> = F1 | F2
1392
+
1393
+ /**
1394
+ * Create an intersection of function types (overload).
1395
+ *
1396
+ * @example
1397
+ * ```
1398
+ * type F1 = (a: number) => string
1399
+ * type F2 = (b: boolean) => number
1400
+ * // Expect: F1 & F2 (creates overload)
1401
+ * type Example1 = FunctionIntersection<F1, F2>
1402
+ * ```
1403
+ */
1404
+ export type FunctionIntersection<F1 extends AnyFunction, F2 extends AnyFunction> = F1 & F2
1405
+
1406
+ /**
1407
+ * Merge two function signatures (parameter union, return intersection).
1408
+ *
1409
+ * @example
1410
+ * ```
1411
+ * type F1 = (a: number) => string
1412
+ * type F2 = (a: number) => number
1413
+ * // Expect: (a: number) => string & number (never)
1414
+ * type Example1 = FunctionMerge<F1, F2>
1415
+ * ```
1416
+ */
1417
+ export type FunctionMerge<F1 extends AnyFunction, F2 extends AnyFunction> =
1418
+ (...args: Parameters<F1> | Parameters<F2>) => ReturnType<F1> & ReturnType<F2>
1419
+
1420
+ type InternalCurry<P extends readonly any[], R> =
1421
+ P extends [infer First, ...infer Rest]
1422
+ ? (arg: First) => (Rest extends [] ? R : InternalCurry<Rest, R>)
1423
+ : R
1424
+ /**
1425
+ * Curry a function type.
1426
+ *
1427
+ * @example
1428
+ * ```
1429
+ * type Func = (a: number, b: string, c: boolean) => void
1430
+ * // Expect: (a: number) => (b: string) => (c: boolean) => void
1431
+ * type Example1 = FunctionCurry<Func>
1432
+ * ```
1433
+ */
1434
+ export type FunctionCurry<F extends AnyFunction> = InternalCurry<Parameters<F>, ReturnType<F>>
1435
+
1436
+ type InternalUncurry<F, Acc extends readonly any[] = []> =
1437
+ F extends (arg: infer A) => infer R
1438
+ ? InternalUncurry<R, [...Acc, A]>
1439
+ : (...args: Acc) => F
1440
+ /**
1441
+ * Uncurry a curried function type.
1442
+ *
1443
+ * @example
1444
+ * ```
1445
+ * type Curried = (a: number) => (b: string) => (c: boolean) => void
1446
+ * // Expect: (a: number, b: string, c: boolean) => void
1447
+ * type Example1 = FunctionUncurry<Curried>
1448
+ * type Single = (a: number) => string
1449
+ * // Expect: (a: number) => string
1450
+ * type Example2 = FunctionUncurry<Single>
1451
+ * ```
1452
+ */
1453
+ export type FunctionUncurry<F> = InternalUncurry<F>
1454
+
1455
+ type InternalPartialApply<P extends readonly any[], Applied extends readonly any[]> =
1456
+ Applied extends []
1457
+ ? P
1458
+ : (P extends [any, ...infer Rest]
1459
+ ? (Applied extends [any, ...infer RestApplied]
1460
+ ? InternalPartialApply<Rest, RestApplied>
1461
+ : P)
1462
+ : P)
1463
+ /**
1464
+ * Partially apply arguments to a function.
1465
+ *
1466
+ * @example
1467
+ * ```
1468
+ * type Func = (a: number, b: string, c: boolean) => void
1469
+ * // Expect: (c: boolean) => void
1470
+ * type Example1 = FunctionPartialApply<Func, [number, string]>
1471
+ * ```
1472
+ */
1473
+ export type FunctionPartialApply<F extends AnyFunction, Args extends readonly any[]> =
1474
+ (...args: InternalPartialApply<Parameters<F>, Args>) => ReturnType<F>
1475
+
1476
+ /**
1477
+ * Bind first N arguments of a function.
1478
+ *
1479
+ * @example
1480
+ * ```
1481
+ * type Func = (a: number, b: string, c: boolean) => void
1482
+ * // Expect: (c: boolean) => void
1483
+ * type Example1 = FunctionBind<Func, [number, string]>
1484
+ * // Expect: (b: string, c: boolean) => void
1485
+ * type Example2 = FunctionBind<Func, [number]>
1486
+ * ```
1487
+ */
1488
+ export type FunctionBind<F extends AnyFunction, BoundArgs extends readonly any[]> =
1489
+ FunctionPartialApply<F, BoundArgs>
1490
+
1491
+ // ============================================================================
1492
+ // Conversion
1493
+ // ============================================================================
1494
+
1495
+ /**
1496
+ * Convert a regular function to a constructor function.
1497
+ *
1498
+ * @example
1499
+ * ```
1500
+ * type Func = (a: number, b: string) => MyClass
1501
+ * // Expect: new (a: number, b: string) => MyClass
1502
+ * type Example1 = FunctionToClassConstructor<Func, MyClass>
1503
+ * ```
1504
+ */
1505
+ export type FunctionToClassConstructor<F extends AnyFunction, Instance> =
1506
+ new (...args: Parameters<F>) => Instance
1507
+
1508
+ /**
1509
+ * Convert a function to an object method signature.
1510
+ *
1511
+ * @example
1512
+ * ```
1513
+ * type Func = (a: number, b: string) => boolean
1514
+ * // Expect: { method(a: number, b: string): boolean }
1515
+ * type Example1 = FunctionToObject<Func, 'method'>
1516
+ * ```
1517
+ */
1518
+ export type FunctionToObject<F extends AnyFunction, Key extends string> =
1519
+ { [K in Key]: F }