@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,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 }
|