@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,732 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Helpers
|
|
3
|
+
// ============================================================================
|
|
4
|
+
|
|
5
|
+
// Internal helper to build array of specified length
|
|
6
|
+
type InternalBuildArray<
|
|
7
|
+
N extends number,
|
|
8
|
+
Acc extends readonly unknown[] = []
|
|
9
|
+
> = Acc['length'] extends N
|
|
10
|
+
? Acc
|
|
11
|
+
: InternalBuildArray<N, [...Acc, unknown]>
|
|
12
|
+
|
|
13
|
+
// ============================================================================
|
|
14
|
+
// Primitives
|
|
15
|
+
// ============================================================================
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Get the sign of a number (-1 for negative, 0 for zero, 1 for positive).
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```
|
|
22
|
+
* // Expect: 1
|
|
23
|
+
* type Example1 = NumberSign<5>
|
|
24
|
+
* // Expect: -1
|
|
25
|
+
* type Example2 = NumberSign<-5>
|
|
26
|
+
* // Expect: 0
|
|
27
|
+
* type Example3 = NumberSign<0>
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export type NumberSign<N extends number> =
|
|
31
|
+
N extends 0
|
|
32
|
+
? 0
|
|
33
|
+
: (NumberIsNegative<N> extends true ? -1 : 1)
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Get the number of digits in a positive integer.
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```
|
|
40
|
+
* // Expect: 1
|
|
41
|
+
* type Example1 = NumberDigitCount<5>
|
|
42
|
+
* // Expect: 3
|
|
43
|
+
* type Example2 = NumberDigitCount<123>
|
|
44
|
+
* // Expect: 1
|
|
45
|
+
* type Example3 = NumberDigitCount<0>
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export type NumberDigitCount<N extends number> =
|
|
49
|
+
NumberAbs<N> extends infer AbsN extends number
|
|
50
|
+
? `${AbsN}` extends `${infer Digits}` ? Digits['length'] : never
|
|
51
|
+
: never
|
|
52
|
+
|
|
53
|
+
// ============================================================================
|
|
54
|
+
// Validation
|
|
55
|
+
// ============================================================================
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Check if a number is zero.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```
|
|
62
|
+
* // Expect: true
|
|
63
|
+
* type Example1 = NumberIsZero<0>
|
|
64
|
+
* // Expect: false
|
|
65
|
+
* type Example2 = NumberIsZero<1>
|
|
66
|
+
* // Expect: false
|
|
67
|
+
* type Example3 = NumberIsZero<-1>
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
export type NumberIsZero<N extends number> = N extends 0 ? true : false
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Check if a number is positive (greater than zero).
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```
|
|
77
|
+
* // Expect: true
|
|
78
|
+
* type Example1 = NumberIsPositive<1>
|
|
79
|
+
* // Expect: true
|
|
80
|
+
* type Example2 = NumberIsPositive<100>
|
|
81
|
+
* // Expect: false
|
|
82
|
+
* type Example3 = NumberIsPositive<0>
|
|
83
|
+
* // Expect: false
|
|
84
|
+
* type Example4 = NumberIsPositive<-1>
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
export type NumberIsPositive<N extends number> =
|
|
88
|
+
`${N}` extends `-${string}` ? false : (N extends 0 ? false : true)
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Check if a number is negative (less than zero).
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* ```
|
|
95
|
+
* // Expect: true
|
|
96
|
+
* type Example1 = NumberIsNegative<-1>
|
|
97
|
+
* // Expect: true
|
|
98
|
+
* type Example2 = NumberIsNegative<-100>
|
|
99
|
+
* // Expect: false
|
|
100
|
+
* type Example3 = NumberIsNegative<0>
|
|
101
|
+
* // Expect: false
|
|
102
|
+
* type Example4 = NumberIsNegative<1>
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
export type NumberIsNegative<N extends number> = `${N}` extends `-${string}` ? true : false
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Check if a number is even.
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```
|
|
112
|
+
* // Expect: true
|
|
113
|
+
* type Example1 = NumberIsEven<0>
|
|
114
|
+
* // Expect: true
|
|
115
|
+
* type Example2 = NumberIsEven<2>
|
|
116
|
+
* // Expect: true
|
|
117
|
+
* type Example3 = NumberIsEven<10>
|
|
118
|
+
* // Expect: false
|
|
119
|
+
* type Example4 = NumberIsEven<1>
|
|
120
|
+
* // Expect: false
|
|
121
|
+
* type Example5 = NumberIsEven<3>
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
export type NumberIsEven<N extends number> =
|
|
125
|
+
`${N}` extends `${string}${'0' | '2' | '4' | '6' | '8'}` ? true : false
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Check if a number is odd.
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```
|
|
132
|
+
* // Expect: true
|
|
133
|
+
* type Example1 = NumberIsOdd<1>
|
|
134
|
+
* // Expect: true
|
|
135
|
+
* type Example2 = NumberIsOdd<3>
|
|
136
|
+
* // Expect: false
|
|
137
|
+
* type Example3 = NumberIsOdd<0>
|
|
138
|
+
* // Expect: false
|
|
139
|
+
* type Example4 = NumberIsOdd<2>
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
142
|
+
export type NumberIsOdd<N extends number> =
|
|
143
|
+
`${N}` extends `${string}${'1' | '3' | '5' | '7' | '9'}` ? true : false
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Check if two numbers are equal.
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```
|
|
150
|
+
* // Expect: true
|
|
151
|
+
* type Example1 = NumberIsEqual<5, 5>
|
|
152
|
+
* // Expect: false
|
|
153
|
+
* type Example2 = NumberIsEqual<5, 10>
|
|
154
|
+
* // Expect: true
|
|
155
|
+
* type Example3 = NumberIsEqual<0, 0>
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
158
|
+
export type NumberIsEqual<A extends number, B extends number> =
|
|
159
|
+
A extends B ? (B extends A ? true : false) : false
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Check if a number is a power of 2.
|
|
163
|
+
*
|
|
164
|
+
* @example
|
|
165
|
+
* ```
|
|
166
|
+
* // Expect: true
|
|
167
|
+
* type Example1 = NumberIsPowerOfTwo<1>
|
|
168
|
+
* // Expect: true
|
|
169
|
+
* type Example2 = NumberIsPowerOfTwo<8>
|
|
170
|
+
* // Expect: false
|
|
171
|
+
* type Example3 = NumberIsPowerOfTwo<6>
|
|
172
|
+
* ```
|
|
173
|
+
*/
|
|
174
|
+
export type NumberIsPowerOfTwo<N extends number> =
|
|
175
|
+
N extends 0
|
|
176
|
+
? false
|
|
177
|
+
: (
|
|
178
|
+
N extends 1
|
|
179
|
+
? true
|
|
180
|
+
: (
|
|
181
|
+
NumberIsEven<N> extends true
|
|
182
|
+
? NumberIsPowerOfTwo<NumberDivide<N, 2>>
|
|
183
|
+
: false
|
|
184
|
+
)
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
// ============================================================================
|
|
188
|
+
// Comparison
|
|
189
|
+
// ============================================================================
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Check if A is greater than B.
|
|
193
|
+
*
|
|
194
|
+
* @example
|
|
195
|
+
* ```
|
|
196
|
+
* // Expect: true
|
|
197
|
+
* type Example1 = NumberGreaterThan<5, 3>
|
|
198
|
+
* // Expect: false
|
|
199
|
+
* type Example2 = NumberGreaterThan<3, 5>
|
|
200
|
+
* // Expect: false
|
|
201
|
+
* type Example3 = NumberGreaterThan<5, 5>
|
|
202
|
+
* ```
|
|
203
|
+
*/
|
|
204
|
+
export type NumberGreaterThan<A extends number, B extends number> =
|
|
205
|
+
InternalBuildArray<A> extends [...InternalBuildArray<B>, ...infer Rest]
|
|
206
|
+
? (Rest extends [unknown, ...unknown[]] ? true : false)
|
|
207
|
+
: false
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Check if A is greater than or equal to B.
|
|
211
|
+
*
|
|
212
|
+
* @example
|
|
213
|
+
* ```
|
|
214
|
+
* // Expect: true
|
|
215
|
+
* type Example1 = NumberGreaterThanOrEqual<5, 3>
|
|
216
|
+
* // Expect: false
|
|
217
|
+
* type Example2 = NumberGreaterThanOrEqual<3, 5>
|
|
218
|
+
* // Expect: true
|
|
219
|
+
* type Example3 = NumberGreaterThanOrEqual<5, 5>
|
|
220
|
+
* ```
|
|
221
|
+
*/
|
|
222
|
+
export type NumberGreaterThanOrEqual<A extends number, B extends number> =
|
|
223
|
+
NumberIsEqual<A, B> extends true ? true : NumberGreaterThan<A, B>
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Check if A is less than B.
|
|
227
|
+
*
|
|
228
|
+
* @example
|
|
229
|
+
* ```
|
|
230
|
+
* // Expect: true
|
|
231
|
+
* type Example1 = NumberLessThan<3, 5>
|
|
232
|
+
* // Expect: false
|
|
233
|
+
* type Example2 = NumberLessThan<5, 3>
|
|
234
|
+
* // Expect: false
|
|
235
|
+
* type Example3 = NumberLessThan<5, 5>
|
|
236
|
+
* ```
|
|
237
|
+
*/
|
|
238
|
+
export type NumberLessThan<A extends number, B extends number> =
|
|
239
|
+
NumberGreaterThan<B, A>
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Check if A is less than or equal to B.
|
|
243
|
+
*
|
|
244
|
+
* @example
|
|
245
|
+
* ```
|
|
246
|
+
* // Expect: true
|
|
247
|
+
* type Example1 = NumberLessThanOrEqual<3, 5>
|
|
248
|
+
* // Expect: false
|
|
249
|
+
* type Example2 = NumberLessThanOrEqual<5, 3>
|
|
250
|
+
* // Expect: true
|
|
251
|
+
* type Example3 = NumberLessThanOrEqual<5, 5>
|
|
252
|
+
* ```
|
|
253
|
+
*/
|
|
254
|
+
export type NumberLessThanOrEqual<A extends number, B extends number> =
|
|
255
|
+
NumberIsEqual<A, B> extends true ? true : NumberLessThan<A, B>
|
|
256
|
+
|
|
257
|
+
// ============================================================================
|
|
258
|
+
// Manipulation
|
|
259
|
+
// ============================================================================
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Add two numbers (limited by TypeScript's recursion depth).
|
|
263
|
+
*
|
|
264
|
+
* @example
|
|
265
|
+
* ```
|
|
266
|
+
* // Expect: 5
|
|
267
|
+
* type Example1 = NumberAdd<2, 3>
|
|
268
|
+
* // Expect: 10
|
|
269
|
+
* type Example2 = NumberAdd<7, 3>
|
|
270
|
+
* // Expect: 0
|
|
271
|
+
* type Example3 = NumberAdd<0, 0>
|
|
272
|
+
* ```
|
|
273
|
+
*/
|
|
274
|
+
export type NumberAdd<A extends number, B extends number> =
|
|
275
|
+
[...InternalBuildArray<A>, ...InternalBuildArray<B>]['length'] extends infer Sum
|
|
276
|
+
? (Sum extends number ? Sum : never)
|
|
277
|
+
: never
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Subtract B from A (limited by TypeScript's recursion depth).
|
|
281
|
+
*
|
|
282
|
+
* @example
|
|
283
|
+
* ```
|
|
284
|
+
* // Expect: 2
|
|
285
|
+
* type Example1 = NumberSubtract<5, 3>
|
|
286
|
+
* // Expect: 0
|
|
287
|
+
* type Example2 = NumberSubtract<3, 3>
|
|
288
|
+
* // Expect: 10
|
|
289
|
+
* type Example3 = NumberSubtract<15, 5>
|
|
290
|
+
* ```
|
|
291
|
+
*/
|
|
292
|
+
export type NumberSubtract<A extends number, B extends number> =
|
|
293
|
+
InternalBuildArray<A> extends [...InternalBuildArray<B>, ...infer Rest]
|
|
294
|
+
? Rest['length']
|
|
295
|
+
: never
|
|
296
|
+
|
|
297
|
+
type InternalNumberMultiply<
|
|
298
|
+
A extends number,
|
|
299
|
+
B extends number,
|
|
300
|
+
Acc extends readonly unknown[] = []
|
|
301
|
+
> = B extends 0
|
|
302
|
+
? Acc['length']
|
|
303
|
+
: InternalNumberMultiply<A, NumberSubtract<B, 1>, [...Acc, ...InternalBuildArray<A>]>
|
|
304
|
+
/**
|
|
305
|
+
* Multiply two numbers (limited by TypeScript's recursion depth).
|
|
306
|
+
*
|
|
307
|
+
* @example
|
|
308
|
+
* ```
|
|
309
|
+
* // Expect: 6
|
|
310
|
+
* type Example1 = NumberMultiply<2, 3>
|
|
311
|
+
* // Expect: 0
|
|
312
|
+
* type Example2 = NumberMultiply<5, 0>
|
|
313
|
+
* // Expect: 25
|
|
314
|
+
* type Example3 = NumberMultiply<5, 5>
|
|
315
|
+
* ```
|
|
316
|
+
*/
|
|
317
|
+
export type NumberMultiply<A extends number, B extends number> =
|
|
318
|
+
InternalNumberMultiply<A, B> extends number ? InternalNumberMultiply<A, B> : never
|
|
319
|
+
|
|
320
|
+
type InternalNumberDivide<
|
|
321
|
+
A extends number,
|
|
322
|
+
B extends number,
|
|
323
|
+
Quotient extends readonly unknown[] = []
|
|
324
|
+
> = NumberGreaterThanOrEqual<A, B> extends true
|
|
325
|
+
? InternalNumberDivide<NumberSubtract<A, B>, B, [...Quotient, unknown]>
|
|
326
|
+
: Quotient['length']
|
|
327
|
+
/**
|
|
328
|
+
* Divide A by B (integer division, limited by TypeScript's recursion depth).
|
|
329
|
+
*
|
|
330
|
+
* @example
|
|
331
|
+
* ```
|
|
332
|
+
* // Expect: 2
|
|
333
|
+
* type Example1 = NumberDivide<6, 3>
|
|
334
|
+
* // Expect: 3
|
|
335
|
+
* type Example2 = NumberDivide<10, 3>
|
|
336
|
+
* // Expect: 5
|
|
337
|
+
* type Example3 = NumberDivide<25, 5>
|
|
338
|
+
* ```
|
|
339
|
+
*/
|
|
340
|
+
export type NumberDivide<A extends number, B extends number> =
|
|
341
|
+
B extends 0
|
|
342
|
+
? never
|
|
343
|
+
: (InternalNumberDivide<A, B> extends number ? InternalNumberDivide<A, B> : never)
|
|
344
|
+
|
|
345
|
+
type InternalNumberModulo<
|
|
346
|
+
A extends number,
|
|
347
|
+
B extends number
|
|
348
|
+
> = NumberGreaterThanOrEqual<A, B> extends true
|
|
349
|
+
? InternalNumberModulo<NumberSubtract<A, B>, B>
|
|
350
|
+
: A
|
|
351
|
+
/**
|
|
352
|
+
* Get the remainder of A divided by B (modulo operation).
|
|
353
|
+
*
|
|
354
|
+
* @example
|
|
355
|
+
* ```
|
|
356
|
+
* // Expect: 0
|
|
357
|
+
* type Example1 = NumberModulo<6, 3>
|
|
358
|
+
* // Expect: 1
|
|
359
|
+
* type Example2 = NumberModulo<10, 3>
|
|
360
|
+
* // Expect: 2
|
|
361
|
+
* type Example3 = NumberModulo<5, 3>
|
|
362
|
+
* ```
|
|
363
|
+
*/
|
|
364
|
+
export type NumberModulo<A extends number, B extends number> =
|
|
365
|
+
B extends 0 ? never : InternalNumberModulo<A, B>
|
|
366
|
+
|
|
367
|
+
type InternalNumberPower<
|
|
368
|
+
Base extends number,
|
|
369
|
+
Exponent extends number,
|
|
370
|
+
Acc extends number = 1
|
|
371
|
+
> = Exponent extends 0
|
|
372
|
+
? Acc
|
|
373
|
+
: InternalNumberPower<Base, NumberSubtract<Exponent, 1>, NumberMultiply<Acc, Base>>
|
|
374
|
+
/**
|
|
375
|
+
* Calculate Base raised to the power of Exponent.
|
|
376
|
+
*
|
|
377
|
+
* @example
|
|
378
|
+
* ```
|
|
379
|
+
* // Expect: 8
|
|
380
|
+
* type Example1 = NumberPower<2, 3>
|
|
381
|
+
* // Expect: 1
|
|
382
|
+
* type Example2 = NumberPower<5, 0>
|
|
383
|
+
* // Expect: 25
|
|
384
|
+
* type Example3 = NumberPower<5, 2>
|
|
385
|
+
* ```
|
|
386
|
+
*/
|
|
387
|
+
export type NumberPower<Base extends number, Exponent extends number> =
|
|
388
|
+
InternalNumberPower<Base, Exponent> extends number ? InternalNumberPower<Base, Exponent> : never
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* Get the absolute value of a number.
|
|
392
|
+
*
|
|
393
|
+
* @example
|
|
394
|
+
* ```
|
|
395
|
+
* // Expect: 5
|
|
396
|
+
* type Example1 = NumberAbs<5>
|
|
397
|
+
* // Expect: 5
|
|
398
|
+
* type Example2 = NumberAbs<-5>
|
|
399
|
+
* // Expect: 0
|
|
400
|
+
* type Example3 = NumberAbs<0>
|
|
401
|
+
* ```
|
|
402
|
+
*/
|
|
403
|
+
export type NumberAbs<N extends number> =
|
|
404
|
+
`${N}` extends `-${infer Positive extends number}` ? Positive : N
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* Negate a number (multiply by -1).
|
|
408
|
+
*
|
|
409
|
+
* @example
|
|
410
|
+
* ```
|
|
411
|
+
* // Expect: -5
|
|
412
|
+
* type Example1 = NumberNegate<5>
|
|
413
|
+
* // Expect: 5
|
|
414
|
+
* type Example2 = NumberNegate<-5>
|
|
415
|
+
* // Expect: 0
|
|
416
|
+
* type Example3 = NumberNegate<0>
|
|
417
|
+
* ```
|
|
418
|
+
*/
|
|
419
|
+
export type NumberNegate<N extends number> =
|
|
420
|
+
N extends 0
|
|
421
|
+
? 0
|
|
422
|
+
: (
|
|
423
|
+
`${N}` extends `-${infer Positive extends number}`
|
|
424
|
+
? Positive
|
|
425
|
+
: (
|
|
426
|
+
`-${N}` extends `${infer Negative extends number}` ? Negative : never
|
|
427
|
+
)
|
|
428
|
+
)
|
|
429
|
+
|
|
430
|
+
/**
|
|
431
|
+
* Increment a number by 1.
|
|
432
|
+
*
|
|
433
|
+
* @example
|
|
434
|
+
* ```
|
|
435
|
+
* // Expect: 1
|
|
436
|
+
* type Example1 = NumberIncrement<0>
|
|
437
|
+
* // Expect: 6
|
|
438
|
+
* type Example2 = NumberIncrement<5>
|
|
439
|
+
* // Expect: 11
|
|
440
|
+
* type Example3 = NumberIncrement<10>
|
|
441
|
+
* ```
|
|
442
|
+
*/
|
|
443
|
+
export type NumberIncrement<N extends number> = NumberAdd<N, 1>
|
|
444
|
+
|
|
445
|
+
/**
|
|
446
|
+
* Decrement a number by 1.
|
|
447
|
+
*
|
|
448
|
+
* @example
|
|
449
|
+
* ```
|
|
450
|
+
* // Expect: 4
|
|
451
|
+
* type Example1 = NumberDecrement<5>
|
|
452
|
+
* // Expect: 9
|
|
453
|
+
* type Example2 = NumberDecrement<10>
|
|
454
|
+
* // Expect: 0
|
|
455
|
+
* type Example3 = NumberDecrement<1>
|
|
456
|
+
* ```
|
|
457
|
+
*/
|
|
458
|
+
export type NumberDecrement<N extends number> = NumberSubtract<N, 1>
|
|
459
|
+
|
|
460
|
+
type InternalNumberSum<
|
|
461
|
+
T extends readonly number[],
|
|
462
|
+
Acc extends number = 0
|
|
463
|
+
> = T extends [infer First extends number, ...infer Rest extends number[]]
|
|
464
|
+
? InternalNumberSum<Rest, NumberAdd<Acc, First>>
|
|
465
|
+
: Acc
|
|
466
|
+
/**
|
|
467
|
+
* Calculate the sum of all numbers in a tuple.
|
|
468
|
+
*
|
|
469
|
+
* @example
|
|
470
|
+
* ```
|
|
471
|
+
* // Expect: 10
|
|
472
|
+
* type Example1 = NumberSum<[1, 2, 3, 4]>
|
|
473
|
+
* // Expect: 0
|
|
474
|
+
* type Example2 = NumberSum<[]>
|
|
475
|
+
* // Expect: 5
|
|
476
|
+
* type Example3 = NumberSum<[5]>
|
|
477
|
+
* ```
|
|
478
|
+
*/
|
|
479
|
+
export type NumberSum<T extends readonly number[]> =
|
|
480
|
+
InternalNumberSum<T> extends number ? InternalNumberSum<T> : never
|
|
481
|
+
|
|
482
|
+
type InternalNumberProduct<
|
|
483
|
+
T extends readonly number[],
|
|
484
|
+
Acc extends number = 1
|
|
485
|
+
> = T extends [infer First extends number, ...infer Rest extends number[]]
|
|
486
|
+
? InternalNumberProduct<Rest, NumberMultiply<Acc, First>>
|
|
487
|
+
: Acc
|
|
488
|
+
/**
|
|
489
|
+
* Calculate the product of all numbers in a tuple.
|
|
490
|
+
*
|
|
491
|
+
* @example
|
|
492
|
+
* ```
|
|
493
|
+
* // Expect: 24
|
|
494
|
+
* type Example1 = NumberProduct<[1, 2, 3, 4]>
|
|
495
|
+
* // Expect: 1
|
|
496
|
+
* type Example2 = NumberProduct<[]>
|
|
497
|
+
* // Expect: 0
|
|
498
|
+
* type Example3 = NumberProduct<[5, 0, 3]>
|
|
499
|
+
* ```
|
|
500
|
+
*/
|
|
501
|
+
export type NumberProduct<T extends readonly number[]> =
|
|
502
|
+
InternalNumberProduct<T> extends number ? InternalNumberProduct<T> : never
|
|
503
|
+
|
|
504
|
+
/**
|
|
505
|
+
* Calculate the average of all numbers in a tuple (integer division).
|
|
506
|
+
*
|
|
507
|
+
* @example
|
|
508
|
+
* ```
|
|
509
|
+
* // Expect: 2
|
|
510
|
+
* type Example1 = NumberAverage<[1, 2, 3, 4]>
|
|
511
|
+
* // Expect: 5
|
|
512
|
+
* type Example2 = NumberAverage<[5, 5, 5]>
|
|
513
|
+
* // Expect: 3
|
|
514
|
+
* type Example3 = NumberAverage<[2, 3, 5]>
|
|
515
|
+
* ```
|
|
516
|
+
*/
|
|
517
|
+
export type NumberAverage<T extends readonly number[]> =
|
|
518
|
+
T extends []
|
|
519
|
+
? never
|
|
520
|
+
: NumberDivide<NumberSum<T>, T['length']>
|
|
521
|
+
|
|
522
|
+
type InternalNumberFactorial<
|
|
523
|
+
N extends number,
|
|
524
|
+
Acc extends number = 1
|
|
525
|
+
> = N extends 0
|
|
526
|
+
? Acc
|
|
527
|
+
: InternalNumberFactorial<NumberDecrement<N>, NumberMultiply<Acc, N>>
|
|
528
|
+
/**
|
|
529
|
+
* Calculate the factorial of a number (N!).
|
|
530
|
+
*
|
|
531
|
+
* @example
|
|
532
|
+
* ```
|
|
533
|
+
* // Expect: 1
|
|
534
|
+
* type Example1 = NumberFactorial<0>
|
|
535
|
+
* // Expect: 1
|
|
536
|
+
* type Example2 = NumberFactorial<1>
|
|
537
|
+
* // Expect: 120
|
|
538
|
+
* type Example3 = NumberFactorial<5>
|
|
539
|
+
* ```
|
|
540
|
+
*/
|
|
541
|
+
export type NumberFactorial<N extends number> =
|
|
542
|
+
InternalNumberFactorial<N> extends number ? InternalNumberFactorial<N> : never
|
|
543
|
+
|
|
544
|
+
type InternalNumberFibonacci<
|
|
545
|
+
N extends number,
|
|
546
|
+
Current extends number = 0,
|
|
547
|
+
Next extends number = 1,
|
|
548
|
+
Counter extends number = 0
|
|
549
|
+
> = Counter extends N
|
|
550
|
+
? Current
|
|
551
|
+
: InternalNumberFibonacci<N, Next, NumberAdd<Current, Next>, NumberIncrement<Counter>>
|
|
552
|
+
/**
|
|
553
|
+
* Get the Nth Fibonacci number (0-indexed).
|
|
554
|
+
*
|
|
555
|
+
* @example
|
|
556
|
+
* ```
|
|
557
|
+
* // Expect: 0
|
|
558
|
+
* type Example1 = NumberFibonacci<0>
|
|
559
|
+
* // Expect: 1
|
|
560
|
+
* type Example2 = NumberFibonacci<1>
|
|
561
|
+
* // Expect: 5
|
|
562
|
+
* type Example3 = NumberFibonacci<5>
|
|
563
|
+
* ```
|
|
564
|
+
*/
|
|
565
|
+
export type NumberFibonacci<N extends number> =
|
|
566
|
+
InternalNumberFibonacci<N> extends number ? InternalNumberFibonacci<N> : never
|
|
567
|
+
|
|
568
|
+
type InternalNumberGCD<A extends number, B extends number> =
|
|
569
|
+
B extends 0
|
|
570
|
+
? A
|
|
571
|
+
: InternalNumberGCD<B, NumberModulo<A, B>>
|
|
572
|
+
/**
|
|
573
|
+
* Calculate the greatest common divisor (GCD) of two numbers.
|
|
574
|
+
*
|
|
575
|
+
* @example
|
|
576
|
+
* ```
|
|
577
|
+
* // Expect: 6
|
|
578
|
+
* type Example1 = NumberGCD<12, 18>
|
|
579
|
+
* // Expect: 1
|
|
580
|
+
* type Example2 = NumberGCD<7, 3>
|
|
581
|
+
* // Expect: 5
|
|
582
|
+
* type Example3 = NumberGCD<15, 5>
|
|
583
|
+
* ```
|
|
584
|
+
*/
|
|
585
|
+
export type NumberGCD<A extends number, B extends number> =
|
|
586
|
+
InternalNumberGCD<A, B> extends number ? InternalNumberGCD<A, B> : never
|
|
587
|
+
|
|
588
|
+
/**
|
|
589
|
+
* Calculate the least common multiple (LCM) of two numbers.
|
|
590
|
+
*
|
|
591
|
+
* @example
|
|
592
|
+
* ```
|
|
593
|
+
* // Expect: 12
|
|
594
|
+
* type Example1 = NumberLCM<3, 4>
|
|
595
|
+
* // Expect: 36
|
|
596
|
+
* type Example2 = NumberLCM<12, 18>
|
|
597
|
+
* // Expect: 15
|
|
598
|
+
* type Example3 = NumberLCM<5, 3>
|
|
599
|
+
* ```
|
|
600
|
+
*/
|
|
601
|
+
export type NumberLCM<A extends number, B extends number> =
|
|
602
|
+
NumberDivide<NumberMultiply<A, B>, NumberGCD<A, B>>
|
|
603
|
+
|
|
604
|
+
type InternalNumberRange<
|
|
605
|
+
From extends number,
|
|
606
|
+
To extends number,
|
|
607
|
+
Acc extends number[] = []
|
|
608
|
+
> = From extends To
|
|
609
|
+
? [...Acc, From]
|
|
610
|
+
: (
|
|
611
|
+
NumberLessThan<From, To> extends true
|
|
612
|
+
? InternalNumberRange<NumberIncrement<From>, To, [...Acc, From]>
|
|
613
|
+
: InternalNumberRange<NumberDecrement<From>, To, [...Acc, From]>
|
|
614
|
+
)
|
|
615
|
+
/**
|
|
616
|
+
* Generate a range of numbers from From to To (inclusive).
|
|
617
|
+
*
|
|
618
|
+
* @example
|
|
619
|
+
* ```
|
|
620
|
+
* // Expect: [1, 2, 3, 4, 5]
|
|
621
|
+
* type Example1 = NumberRange<1, 5>
|
|
622
|
+
* // Expect: [0, 1, 2]
|
|
623
|
+
* type Example2 = NumberRange<0, 2>
|
|
624
|
+
* // Expect: [5, 4, 3]
|
|
625
|
+
* type Example3 = NumberRange<5, 3>
|
|
626
|
+
* ```
|
|
627
|
+
*/
|
|
628
|
+
export type NumberRange<From extends number, To extends number> = InternalNumberRange<From, To>
|
|
629
|
+
|
|
630
|
+
/**
|
|
631
|
+
* Get the minimum value from a tuple of numbers.
|
|
632
|
+
*
|
|
633
|
+
* @example
|
|
634
|
+
* ```
|
|
635
|
+
* // Expect: 1
|
|
636
|
+
* type Example1 = NumberMin<[3, 1, 4, 2]>
|
|
637
|
+
* // Expect: 0
|
|
638
|
+
* type Example2 = NumberMin<[5, 0, 10]>
|
|
639
|
+
* // Expect: 5
|
|
640
|
+
* type Example3 = NumberMin<[5]>
|
|
641
|
+
* ```
|
|
642
|
+
*/
|
|
643
|
+
export type NumberMin<T extends readonly number[]> =
|
|
644
|
+
T extends [infer First extends number, ...infer Rest extends number[]]
|
|
645
|
+
? (
|
|
646
|
+
Rest extends []
|
|
647
|
+
? First
|
|
648
|
+
: (
|
|
649
|
+
NumberMin<Rest> extends infer RestMin extends number
|
|
650
|
+
? (NumberLessThan<First, RestMin> extends true ? First : RestMin)
|
|
651
|
+
: never
|
|
652
|
+
)
|
|
653
|
+
)
|
|
654
|
+
: never
|
|
655
|
+
|
|
656
|
+
/**
|
|
657
|
+
* Get the maximum value from a tuple of numbers.
|
|
658
|
+
*
|
|
659
|
+
* @example
|
|
660
|
+
* ```
|
|
661
|
+
* // Expect: 4
|
|
662
|
+
* type Example1 = NumberMax<[3, 1, 4, 2]>
|
|
663
|
+
* // Expect: 10
|
|
664
|
+
* type Example2 = NumberMax<[5, 0, 10]>
|
|
665
|
+
* // Expect: 5
|
|
666
|
+
* type Example3 = NumberMax<[5]>
|
|
667
|
+
* ```
|
|
668
|
+
*/
|
|
669
|
+
export type NumberMax<T extends readonly number[]> =
|
|
670
|
+
T extends [infer First extends number, ...infer Rest extends number[]]
|
|
671
|
+
? (
|
|
672
|
+
Rest extends []
|
|
673
|
+
? First
|
|
674
|
+
: (
|
|
675
|
+
NumberMax<Rest> extends infer RestMax extends number
|
|
676
|
+
? (NumberGreaterThan<First, RestMax> extends true ? First : RestMax)
|
|
677
|
+
: never
|
|
678
|
+
)
|
|
679
|
+
)
|
|
680
|
+
: never
|
|
681
|
+
|
|
682
|
+
/**
|
|
683
|
+
* Clamp a number between a minimum and maximum value.
|
|
684
|
+
*
|
|
685
|
+
* @example
|
|
686
|
+
* ```
|
|
687
|
+
* // Expect: 5
|
|
688
|
+
* type Example1 = NumberClamp<3, 5, 10>
|
|
689
|
+
* // Expect: 7
|
|
690
|
+
* type Example2 = NumberClamp<7, 5, 10>
|
|
691
|
+
* // Expect: 10
|
|
692
|
+
* type Example3 = NumberClamp<15, 5, 10>
|
|
693
|
+
* ```
|
|
694
|
+
*/
|
|
695
|
+
export type NumberClamp<Value extends number, Min extends number, Max extends number> =
|
|
696
|
+
NumberLessThan<Value, Min> extends true
|
|
697
|
+
? Min
|
|
698
|
+
: (NumberGreaterThan<Value, Max> extends true ? Max : Value)
|
|
699
|
+
|
|
700
|
+
// ============================================================================
|
|
701
|
+
// Number Conversion
|
|
702
|
+
// ============================================================================
|
|
703
|
+
|
|
704
|
+
/**
|
|
705
|
+
* Convert a number to a string literal type.
|
|
706
|
+
*
|
|
707
|
+
* @example
|
|
708
|
+
* ```
|
|
709
|
+
* // Expect: '5'
|
|
710
|
+
* type Example1 = NumberToString<5>
|
|
711
|
+
* // Expect: '0'
|
|
712
|
+
* type Example2 = NumberToString<0>
|
|
713
|
+
* // Expect: '-10'
|
|
714
|
+
* type Example3 = NumberToString<-10>
|
|
715
|
+
* ```
|
|
716
|
+
*/
|
|
717
|
+
export type NumberToString<N extends number> = `${N}`
|
|
718
|
+
|
|
719
|
+
/**
|
|
720
|
+
* Convert a number to a boolean (0 = false, non-zero = true).
|
|
721
|
+
*
|
|
722
|
+
* @example
|
|
723
|
+
* ```
|
|
724
|
+
* // Expect: false
|
|
725
|
+
* type Example1 = NumberToBoolean<0>
|
|
726
|
+
* // Expect: true
|
|
727
|
+
* type Example2 = NumberToBoolean<5>
|
|
728
|
+
* // Expect: true
|
|
729
|
+
* type Example3 = NumberToBoolean<-3>
|
|
730
|
+
* ```
|
|
731
|
+
*/
|
|
732
|
+
export type NumberToBoolean<N extends number> = N extends 0 ? false : true
|