@planet-matrix/mobius-model 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +30 -1
  3. package/dist/index.js +4 -2
  4. package/dist/index.js.map +22 -4
  5. package/package.json +3 -3
  6. package/scripts/build.ts +4 -4
  7. package/src/basic/README.md +144 -0
  8. package/src/basic/array.ts +872 -0
  9. package/src/basic/bigint.ts +114 -0
  10. package/src/basic/boolean.ts +180 -0
  11. package/src/basic/enhance.ts +10 -0
  12. package/src/basic/error.ts +51 -0
  13. package/src/basic/function.ts +453 -0
  14. package/src/basic/helper.ts +276 -0
  15. package/src/basic/index.ts +17 -0
  16. package/src/basic/is.ts +320 -0
  17. package/src/basic/number.ts +178 -0
  18. package/src/basic/object.ts +140 -0
  19. package/src/basic/promise.ts +464 -0
  20. package/src/basic/regexp.ts +7 -0
  21. package/src/basic/stream.ts +140 -0
  22. package/src/basic/string.ts +308 -0
  23. package/src/basic/symbol.ts +164 -0
  24. package/src/basic/temporal.ts +224 -0
  25. package/src/encoding/README.md +105 -0
  26. package/src/encoding/base64.ts +98 -0
  27. package/src/encoding/index.ts +1 -0
  28. package/src/index.ts +4 -0
  29. package/src/random/README.md +109 -0
  30. package/src/random/index.ts +1 -0
  31. package/src/random/uuid.ts +103 -0
  32. package/src/type/README.md +330 -0
  33. package/src/type/array.ts +5 -0
  34. package/src/type/boolean.ts +471 -0
  35. package/src/type/class.ts +419 -0
  36. package/src/type/function.ts +1519 -0
  37. package/src/type/helper.ts +135 -0
  38. package/src/type/index.ts +14 -0
  39. package/src/type/intersection.ts +93 -0
  40. package/src/type/is.ts +247 -0
  41. package/src/type/iteration.ts +233 -0
  42. package/src/type/number.ts +732 -0
  43. package/src/type/object.ts +788 -0
  44. package/src/type/path.ts +73 -0
  45. package/src/type/string.ts +1004 -0
  46. package/src/type/tuple.ts +2424 -0
  47. package/src/type/union.ts +108 -0
  48. package/tests/unit/basic/array.spec.ts +290 -0
  49. package/tests/unit/basic/bigint.spec.ts +50 -0
  50. package/tests/unit/basic/boolean.spec.ts +74 -0
  51. package/tests/unit/basic/error.spec.ts +32 -0
  52. package/tests/unit/basic/function.spec.ts +175 -0
  53. package/tests/unit/basic/helper.spec.ts +118 -0
  54. package/tests/unit/basic/number.spec.ts +74 -0
  55. package/tests/unit/basic/object.spec.ts +46 -0
  56. package/tests/unit/basic/promise.spec.ts +232 -0
  57. package/tests/unit/basic/regexp.spec.ts +11 -0
  58. package/tests/unit/basic/stream.spec.ts +120 -0
  59. package/tests/unit/basic/string.spec.ts +74 -0
  60. package/tests/unit/basic/symbol.spec.ts +72 -0
  61. package/tests/unit/basic/temporal.spec.ts +78 -0
  62. package/tests/unit/encoding/base64.spec.ts +40 -0
  63. package/tests/unit/random/uuid.spec.ts +37 -0
  64. package/dist/index.d.ts +0 -2
  65. package/dist/index.d.ts.map +0 -1
  66. package/dist/reactor/index.d.ts +0 -3
  67. package/dist/reactor/index.d.ts.map +0 -1
  68. package/dist/reactor/reactor-core/flags.d.ts +0 -99
  69. package/dist/reactor/reactor-core/flags.d.ts.map +0 -1
  70. package/dist/reactor/reactor-core/index.d.ts +0 -4
  71. package/dist/reactor/reactor-core/index.d.ts.map +0 -1
  72. package/dist/reactor/reactor-core/primitive.d.ts +0 -276
  73. package/dist/reactor/reactor-core/primitive.d.ts.map +0 -1
  74. package/dist/reactor/reactor-core/reactive-system.d.ts +0 -241
  75. package/dist/reactor/reactor-core/reactive-system.d.ts.map +0 -1
  76. package/dist/reactor/reactor-operators/branch.d.ts +0 -19
  77. package/dist/reactor/reactor-operators/branch.d.ts.map +0 -1
  78. package/dist/reactor/reactor-operators/convert.d.ts +0 -30
  79. package/dist/reactor/reactor-operators/convert.d.ts.map +0 -1
  80. package/dist/reactor/reactor-operators/create.d.ts +0 -26
  81. package/dist/reactor/reactor-operators/create.d.ts.map +0 -1
  82. package/dist/reactor/reactor-operators/filter.d.ts +0 -269
  83. package/dist/reactor/reactor-operators/filter.d.ts.map +0 -1
  84. package/dist/reactor/reactor-operators/index.d.ts +0 -8
  85. package/dist/reactor/reactor-operators/index.d.ts.map +0 -1
  86. package/dist/reactor/reactor-operators/join.d.ts +0 -48
  87. package/dist/reactor/reactor-operators/join.d.ts.map +0 -1
  88. package/dist/reactor/reactor-operators/map.d.ts +0 -165
  89. package/dist/reactor/reactor-operators/map.d.ts.map +0 -1
  90. package/dist/reactor/reactor-operators/utility.d.ts +0 -48
  91. package/dist/reactor/reactor-operators/utility.d.ts.map +0 -1
@@ -0,0 +1,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