ts-data-forge 14.10.2 → 14.11.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 (416) hide show
  1. package/README.md +34 -1
  2. package/dist/array/impl/array-utils-reducing-value.d.mts.map +1 -1
  3. package/dist/array/impl/array-utils-reducing-value.mjs +4 -3
  4. package/dist/array/impl/array-utils-reducing-value.mjs.map +1 -1
  5. package/dist/array/impl/array-utils-slice-clamped.mjs +1 -1
  6. package/dist/array/impl/array-utils-slice-clamped.mjs.map +1 -1
  7. package/dist/array/impl/array-utils-slicing.d.mts.map +1 -1
  8. package/dist/array/impl/array-utils-slicing.mjs +10 -3
  9. package/dist/array/impl/array-utils-slicing.mjs.map +1 -1
  10. package/dist/array/impl/array-utils-transformation.d.mts.map +1 -1
  11. package/dist/array/impl/array-utils-transformation.mjs +2 -2
  12. package/dist/array/impl/array-utils-transformation.mjs.map +1 -1
  13. package/dist/array/impl/array-utils-validation.d.mts.map +1 -1
  14. package/dist/array/impl/array-utils-validation.mjs +2 -1
  15. package/dist/array/impl/array-utils-validation.mjs.map +1 -1
  16. package/dist/built-in-tag.d.mts +22 -0
  17. package/dist/built-in-tag.d.mts.map +1 -0
  18. package/dist/built-in-tag.mjs +34 -0
  19. package/dist/built-in-tag.mjs.map +1 -0
  20. package/dist/collections/stack.mjs +3 -3
  21. package/dist/collections/stack.mjs.map +1 -1
  22. package/dist/iterator/range.d.mts +1 -1
  23. package/dist/iterator/range.d.mts.map +1 -1
  24. package/dist/iterator/range.mjs +5 -2
  25. package/dist/iterator/range.mjs.map +1 -1
  26. package/dist/number/branded-types/finite-number.d.mts +4 -9
  27. package/dist/number/branded-types/finite-number.d.mts.map +1 -1
  28. package/dist/number/branded-types/finite-number.mjs +9 -9
  29. package/dist/number/branded-types/finite-number.mjs.map +1 -1
  30. package/dist/number/branded-types/int.d.mts +3 -9
  31. package/dist/number/branded-types/int.d.mts.map +1 -1
  32. package/dist/number/branded-types/int.mjs +9 -10
  33. package/dist/number/branded-types/int.mjs.map +1 -1
  34. package/dist/number/branded-types/int16.d.mts +3 -18
  35. package/dist/number/branded-types/int16.d.mts.map +1 -1
  36. package/dist/number/branded-types/int16.mjs +9 -10
  37. package/dist/number/branded-types/int16.mjs.map +1 -1
  38. package/dist/number/branded-types/int32.d.mts +3 -14
  39. package/dist/number/branded-types/int32.d.mts.map +1 -1
  40. package/dist/number/branded-types/int32.mjs +9 -10
  41. package/dist/number/branded-types/int32.mjs.map +1 -1
  42. package/dist/number/branded-types/negative-finite-number.d.mts +4 -16
  43. package/dist/number/branded-types/negative-finite-number.d.mts.map +1 -1
  44. package/dist/number/branded-types/negative-finite-number.mjs +9 -10
  45. package/dist/number/branded-types/negative-finite-number.mjs.map +1 -1
  46. package/dist/number/branded-types/negative-int.d.mts +3 -16
  47. package/dist/number/branded-types/negative-int.d.mts.map +1 -1
  48. package/dist/number/branded-types/negative-int.mjs +9 -11
  49. package/dist/number/branded-types/negative-int.mjs.map +1 -1
  50. package/dist/number/branded-types/negative-safe-int.d.mts +3 -17
  51. package/dist/number/branded-types/negative-safe-int.d.mts.map +1 -1
  52. package/dist/number/branded-types/negative-safe-int.mjs +9 -11
  53. package/dist/number/branded-types/negative-safe-int.mjs.map +1 -1
  54. package/dist/number/branded-types/non-negative-finite-number.d.mts +4 -14
  55. package/dist/number/branded-types/non-negative-finite-number.d.mts.map +1 -1
  56. package/dist/number/branded-types/non-negative-finite-number.mjs +9 -9
  57. package/dist/number/branded-types/non-negative-finite-number.mjs.map +1 -1
  58. package/dist/number/branded-types/non-negative-int16.d.mts +3 -19
  59. package/dist/number/branded-types/non-negative-int16.d.mts.map +1 -1
  60. package/dist/number/branded-types/non-negative-int16.mjs +9 -10
  61. package/dist/number/branded-types/non-negative-int16.mjs.map +1 -1
  62. package/dist/number/branded-types/non-negative-int32.d.mts +3 -17
  63. package/dist/number/branded-types/non-negative-int32.d.mts.map +1 -1
  64. package/dist/number/branded-types/non-negative-int32.mjs +9 -10
  65. package/dist/number/branded-types/non-negative-int32.mjs.map +1 -1
  66. package/dist/number/branded-types/non-positive-finite-number.d.mts +4 -14
  67. package/dist/number/branded-types/non-positive-finite-number.d.mts.map +1 -1
  68. package/dist/number/branded-types/non-positive-finite-number.mjs +9 -9
  69. package/dist/number/branded-types/non-positive-finite-number.mjs.map +1 -1
  70. package/dist/number/branded-types/non-positive-int.d.mts +3 -14
  71. package/dist/number/branded-types/non-positive-int.d.mts.map +1 -1
  72. package/dist/number/branded-types/non-positive-int.mjs +9 -10
  73. package/dist/number/branded-types/non-positive-int.mjs.map +1 -1
  74. package/dist/number/branded-types/non-positive-safe-int.d.mts +3 -15
  75. package/dist/number/branded-types/non-positive-safe-int.d.mts.map +1 -1
  76. package/dist/number/branded-types/non-positive-safe-int.mjs +9 -10
  77. package/dist/number/branded-types/non-positive-safe-int.mjs.map +1 -1
  78. package/dist/number/branded-types/non-zero-finite-number.d.mts +4 -10
  79. package/dist/number/branded-types/non-zero-finite-number.d.mts.map +1 -1
  80. package/dist/number/branded-types/non-zero-finite-number.mjs +9 -10
  81. package/dist/number/branded-types/non-zero-finite-number.mjs.map +1 -1
  82. package/dist/number/branded-types/non-zero-int.d.mts +3 -10
  83. package/dist/number/branded-types/non-zero-int.d.mts.map +1 -1
  84. package/dist/number/branded-types/non-zero-int.mjs +9 -11
  85. package/dist/number/branded-types/non-zero-int.mjs.map +1 -1
  86. package/dist/number/branded-types/non-zero-int16.d.mts +3 -19
  87. package/dist/number/branded-types/non-zero-int16.d.mts.map +1 -1
  88. package/dist/number/branded-types/non-zero-int16.mjs +12 -11
  89. package/dist/number/branded-types/non-zero-int16.mjs.map +1 -1
  90. package/dist/number/branded-types/non-zero-int32.d.mts +3 -15
  91. package/dist/number/branded-types/non-zero-int32.d.mts.map +1 -1
  92. package/dist/number/branded-types/non-zero-int32.mjs +12 -11
  93. package/dist/number/branded-types/non-zero-int32.mjs.map +1 -1
  94. package/dist/number/branded-types/non-zero-safe-int.d.mts +6 -14
  95. package/dist/number/branded-types/non-zero-safe-int.d.mts.map +1 -1
  96. package/dist/number/branded-types/non-zero-safe-int.mjs +9 -13
  97. package/dist/number/branded-types/non-zero-safe-int.mjs.map +1 -1
  98. package/dist/number/branded-types/non-zero-uint16.d.mts +3 -20
  99. package/dist/number/branded-types/non-zero-uint16.d.mts.map +1 -1
  100. package/dist/number/branded-types/non-zero-uint16.mjs +9 -11
  101. package/dist/number/branded-types/non-zero-uint16.mjs.map +1 -1
  102. package/dist/number/branded-types/non-zero-uint32.d.mts +3 -18
  103. package/dist/number/branded-types/non-zero-uint32.d.mts.map +1 -1
  104. package/dist/number/branded-types/non-zero-uint32.mjs +9 -11
  105. package/dist/number/branded-types/non-zero-uint32.mjs.map +1 -1
  106. package/dist/number/branded-types/positive-finite-number.d.mts +4 -16
  107. package/dist/number/branded-types/positive-finite-number.d.mts.map +1 -1
  108. package/dist/number/branded-types/positive-finite-number.mjs +9 -9
  109. package/dist/number/branded-types/positive-finite-number.mjs.map +1 -1
  110. package/dist/number/branded-types/positive-int.d.mts +3 -16
  111. package/dist/number/branded-types/positive-int.d.mts.map +1 -1
  112. package/dist/number/branded-types/positive-int.mjs +9 -10
  113. package/dist/number/branded-types/positive-int.mjs.map +1 -1
  114. package/dist/number/branded-types/positive-int16.d.mts +3 -21
  115. package/dist/number/branded-types/positive-int16.d.mts.map +1 -1
  116. package/dist/number/branded-types/positive-int16.mjs +9 -10
  117. package/dist/number/branded-types/positive-int16.mjs.map +1 -1
  118. package/dist/number/branded-types/positive-int32.d.mts +3 -19
  119. package/dist/number/branded-types/positive-int32.d.mts.map +1 -1
  120. package/dist/number/branded-types/positive-int32.mjs +9 -10
  121. package/dist/number/branded-types/positive-int32.mjs.map +1 -1
  122. package/dist/number/branded-types/positive-safe-int.d.mts +5 -19
  123. package/dist/number/branded-types/positive-safe-int.d.mts.map +1 -1
  124. package/dist/number/branded-types/positive-safe-int.mjs +9 -11
  125. package/dist/number/branded-types/positive-safe-int.mjs.map +1 -1
  126. package/dist/number/branded-types/positive-uint16.d.mts +3 -20
  127. package/dist/number/branded-types/positive-uint16.d.mts.map +1 -1
  128. package/dist/number/branded-types/positive-uint16.mjs +9 -10
  129. package/dist/number/branded-types/positive-uint16.mjs.map +1 -1
  130. package/dist/number/branded-types/positive-uint32.d.mts +3 -18
  131. package/dist/number/branded-types/positive-uint32.d.mts.map +1 -1
  132. package/dist/number/branded-types/positive-uint32.mjs +9 -10
  133. package/dist/number/branded-types/positive-uint32.mjs.map +1 -1
  134. package/dist/number/branded-types/safe-int.d.mts +5 -12
  135. package/dist/number/branded-types/safe-int.d.mts.map +1 -1
  136. package/dist/number/branded-types/safe-int.mjs +9 -12
  137. package/dist/number/branded-types/safe-int.mjs.map +1 -1
  138. package/dist/number/branded-types/safe-uint.d.mts +3 -15
  139. package/dist/number/branded-types/safe-uint.d.mts.map +1 -1
  140. package/dist/number/branded-types/safe-uint.mjs +9 -11
  141. package/dist/number/branded-types/safe-uint.mjs.map +1 -1
  142. package/dist/number/branded-types/uint.d.mts +3 -14
  143. package/dist/number/branded-types/uint.d.mts.map +1 -1
  144. package/dist/number/branded-types/uint.mjs +9 -10
  145. package/dist/number/branded-types/uint.mjs.map +1 -1
  146. package/dist/number/branded-types/uint16.d.mts +3 -18
  147. package/dist/number/branded-types/uint16.d.mts.map +1 -1
  148. package/dist/number/branded-types/uint16.mjs +9 -10
  149. package/dist/number/branded-types/uint16.mjs.map +1 -1
  150. package/dist/number/branded-types/uint32.d.mts +3 -16
  151. package/dist/number/branded-types/uint32.d.mts.map +1 -1
  152. package/dist/number/branded-types/uint32.mjs +9 -10
  153. package/dist/number/branded-types/uint32.mjs.map +1 -1
  154. package/dist/number/enum/int8.d.mts +13 -15
  155. package/dist/number/enum/int8.d.mts.map +1 -1
  156. package/dist/number/enum/int8.mjs +20 -25
  157. package/dist/number/enum/int8.mjs.map +1 -1
  158. package/dist/number/enum/uint8.d.mts +12 -14
  159. package/dist/number/enum/uint8.d.mts.map +1 -1
  160. package/dist/number/enum/uint8.mjs +18 -23
  161. package/dist/number/enum/uint8.mjs.map +1 -1
  162. package/dist/number/index.d.mts +1 -1
  163. package/dist/number/index.d.mts.map +1 -1
  164. package/dist/number/index.mjs +1 -1
  165. package/dist/number/index.mjs.map +1 -1
  166. package/dist/number/num/impl/index.d.mts +2 -0
  167. package/dist/number/num/impl/index.d.mts.map +1 -0
  168. package/dist/number/num/impl/index.mjs +2 -0
  169. package/dist/number/num/impl/index.mjs.map +1 -0
  170. package/dist/number/num/impl/num.d.mts +531 -0
  171. package/dist/number/num/impl/num.d.mts.map +1 -0
  172. package/dist/number/num/impl/num.mjs +542 -0
  173. package/dist/number/num/impl/num.mjs.map +1 -0
  174. package/dist/number/num/index.d.mts +17 -0
  175. package/dist/number/num/index.d.mts.map +1 -0
  176. package/dist/number/num/index.mjs +17 -0
  177. package/dist/number/num/index.mjs.map +1 -0
  178. package/dist/number/operators/finite-number.d.mts +16 -0
  179. package/dist/number/operators/finite-number.d.mts.map +1 -0
  180. package/dist/number/operators/finite-number.mjs +7 -0
  181. package/dist/number/operators/finite-number.mjs.map +1 -0
  182. package/dist/number/operators/int.d.mts +16 -0
  183. package/dist/number/operators/int.d.mts.map +1 -0
  184. package/dist/number/operators/int.mjs +8 -0
  185. package/dist/number/operators/int.mjs.map +1 -0
  186. package/dist/number/operators/int16.d.mts +25 -0
  187. package/dist/number/operators/int16.d.mts.map +1 -0
  188. package/dist/number/operators/int16.mjs +8 -0
  189. package/dist/number/operators/int16.mjs.map +1 -0
  190. package/dist/number/operators/int32.d.mts +21 -0
  191. package/dist/number/operators/int32.d.mts.map +1 -0
  192. package/dist/number/operators/int32.mjs +8 -0
  193. package/dist/number/operators/int32.mjs.map +1 -0
  194. package/dist/number/operators/int8.d.mts +24 -0
  195. package/dist/number/operators/int8.d.mts.map +1 -0
  196. package/dist/number/operators/int8.mjs +8 -0
  197. package/dist/number/operators/int8.mjs.map +1 -0
  198. package/dist/number/operators/negative-finite-number.d.mts +11 -0
  199. package/dist/number/operators/negative-finite-number.d.mts.map +1 -0
  200. package/dist/number/operators/negative-finite-number.mjs +8 -0
  201. package/dist/number/operators/negative-finite-number.mjs.map +1 -0
  202. package/dist/number/operators/negative-int.d.mts +10 -0
  203. package/dist/number/operators/negative-int.d.mts.map +1 -0
  204. package/dist/number/operators/negative-int.mjs +9 -0
  205. package/dist/number/operators/negative-int.mjs.map +1 -0
  206. package/dist/number/operators/negative-safe-int.d.mts +10 -0
  207. package/dist/number/operators/negative-safe-int.d.mts.map +1 -0
  208. package/dist/number/operators/negative-safe-int.mjs +9 -0
  209. package/dist/number/operators/negative-safe-int.mjs.map +1 -0
  210. package/dist/number/operators/non-negative-finite-number.d.mts +22 -0
  211. package/dist/number/operators/non-negative-finite-number.d.mts.map +1 -0
  212. package/dist/number/operators/non-negative-finite-number.mjs +7 -0
  213. package/dist/number/operators/non-negative-finite-number.mjs.map +1 -0
  214. package/dist/number/operators/non-negative-int16.d.mts +27 -0
  215. package/dist/number/operators/non-negative-int16.d.mts.map +1 -0
  216. package/dist/number/operators/non-negative-int16.mjs +8 -0
  217. package/dist/number/operators/non-negative-int16.mjs.map +1 -0
  218. package/dist/number/operators/non-negative-int32.d.mts +25 -0
  219. package/dist/number/operators/non-negative-int32.d.mts.map +1 -0
  220. package/dist/number/operators/non-negative-int32.mjs +8 -0
  221. package/dist/number/operators/non-negative-int32.mjs.map +1 -0
  222. package/dist/number/operators/non-positive-finite-number.d.mts +11 -0
  223. package/dist/number/operators/non-positive-finite-number.d.mts.map +1 -0
  224. package/dist/number/operators/non-positive-finite-number.mjs +7 -0
  225. package/dist/number/operators/non-positive-finite-number.mjs.map +1 -0
  226. package/dist/number/operators/non-positive-int.d.mts +10 -0
  227. package/dist/number/operators/non-positive-int.d.mts.map +1 -0
  228. package/dist/number/operators/non-positive-int.mjs +8 -0
  229. package/dist/number/operators/non-positive-int.mjs.map +1 -0
  230. package/dist/number/operators/non-positive-safe-int.d.mts +10 -0
  231. package/dist/number/operators/non-positive-safe-int.d.mts.map +1 -0
  232. package/dist/number/operators/non-positive-safe-int.mjs +8 -0
  233. package/dist/number/operators/non-positive-safe-int.mjs.map +1 -0
  234. package/dist/number/operators/non-zero-finite-number.d.mts +16 -0
  235. package/dist/number/operators/non-zero-finite-number.d.mts.map +1 -0
  236. package/dist/number/operators/non-zero-finite-number.mjs +8 -0
  237. package/dist/number/operators/non-zero-finite-number.mjs.map +1 -0
  238. package/dist/number/operators/non-zero-int.d.mts +10 -0
  239. package/dist/number/operators/non-zero-int.d.mts.map +1 -0
  240. package/dist/number/operators/non-zero-int.mjs +9 -0
  241. package/dist/number/operators/non-zero-int.mjs.map +1 -0
  242. package/dist/number/operators/non-zero-int16.d.mts +10 -0
  243. package/dist/number/operators/non-zero-int16.d.mts.map +1 -0
  244. package/dist/number/operators/non-zero-int16.mjs +9 -0
  245. package/dist/number/operators/non-zero-int16.mjs.map +1 -0
  246. package/dist/number/operators/non-zero-int32.d.mts +10 -0
  247. package/dist/number/operators/non-zero-int32.d.mts.map +1 -0
  248. package/dist/number/operators/non-zero-int32.mjs +9 -0
  249. package/dist/number/operators/non-zero-int32.mjs.map +1 -0
  250. package/dist/number/operators/non-zero-safe-int.d.mts +10 -0
  251. package/dist/number/operators/non-zero-safe-int.d.mts.map +1 -0
  252. package/dist/number/operators/non-zero-safe-int.mjs +11 -0
  253. package/dist/number/operators/non-zero-safe-int.mjs.map +1 -0
  254. package/dist/number/operators/non-zero-uint16.d.mts +2 -0
  255. package/dist/number/operators/non-zero-uint16.d.mts.map +1 -0
  256. package/dist/number/operators/non-zero-uint16.mjs +9 -0
  257. package/dist/number/operators/non-zero-uint16.mjs.map +1 -0
  258. package/dist/number/operators/non-zero-uint32.d.mts +2 -0
  259. package/dist/number/operators/non-zero-uint32.d.mts.map +1 -0
  260. package/dist/number/operators/non-zero-uint32.mjs +9 -0
  261. package/dist/number/operators/non-zero-uint32.mjs.map +1 -0
  262. package/dist/number/operators/positive-finite-number.d.mts +23 -0
  263. package/dist/number/operators/positive-finite-number.d.mts.map +1 -0
  264. package/dist/number/operators/positive-finite-number.mjs +7 -0
  265. package/dist/number/operators/positive-finite-number.mjs.map +1 -0
  266. package/dist/number/operators/positive-int.d.mts +23 -0
  267. package/dist/number/operators/positive-int.d.mts.map +1 -0
  268. package/dist/number/operators/positive-int.mjs +8 -0
  269. package/dist/number/operators/positive-int.mjs.map +1 -0
  270. package/dist/number/operators/positive-int16.d.mts +28 -0
  271. package/dist/number/operators/positive-int16.d.mts.map +1 -0
  272. package/dist/number/operators/positive-int16.mjs +8 -0
  273. package/dist/number/operators/positive-int16.mjs.map +1 -0
  274. package/dist/number/operators/positive-int32.d.mts +26 -0
  275. package/dist/number/operators/positive-int32.d.mts.map +1 -0
  276. package/dist/number/operators/positive-int32.mjs +8 -0
  277. package/dist/number/operators/positive-int32.mjs.map +1 -0
  278. package/dist/number/operators/positive-safe-int.d.mts +24 -0
  279. package/dist/number/operators/positive-safe-int.d.mts.map +1 -0
  280. package/dist/number/operators/positive-safe-int.mjs +9 -0
  281. package/dist/number/operators/positive-safe-int.mjs.map +1 -0
  282. package/dist/number/operators/positive-uint16.d.mts +27 -0
  283. package/dist/number/operators/positive-uint16.d.mts.map +1 -0
  284. package/dist/number/operators/positive-uint16.mjs +8 -0
  285. package/dist/number/operators/positive-uint16.mjs.map +1 -0
  286. package/dist/number/operators/positive-uint32.d.mts +25 -0
  287. package/dist/number/operators/positive-uint32.d.mts.map +1 -0
  288. package/dist/number/operators/positive-uint32.mjs +8 -0
  289. package/dist/number/operators/positive-uint32.mjs.map +1 -0
  290. package/dist/number/operators/safe-int.d.mts +17 -0
  291. package/dist/number/operators/safe-int.d.mts.map +1 -0
  292. package/dist/number/operators/safe-int.mjs +10 -0
  293. package/dist/number/operators/safe-int.mjs.map +1 -0
  294. package/dist/number/operators/safe-uint.d.mts +22 -0
  295. package/dist/number/operators/safe-uint.d.mts.map +1 -0
  296. package/dist/number/operators/safe-uint.mjs +9 -0
  297. package/dist/number/operators/safe-uint.mjs.map +1 -0
  298. package/dist/number/operators/uint.d.mts +14 -0
  299. package/dist/number/operators/uint.d.mts.map +1 -0
  300. package/dist/number/operators/uint.mjs +8 -0
  301. package/dist/number/operators/uint.mjs.map +1 -0
  302. package/dist/number/operators/uint16.d.mts +25 -0
  303. package/dist/number/operators/uint16.d.mts.map +1 -0
  304. package/dist/number/operators/uint16.mjs +8 -0
  305. package/dist/number/operators/uint16.mjs.map +1 -0
  306. package/dist/number/operators/uint32.d.mts +23 -0
  307. package/dist/number/operators/uint32.d.mts.map +1 -0
  308. package/dist/number/operators/uint32.mjs +8 -0
  309. package/dist/number/operators/uint32.mjs.map +1 -0
  310. package/dist/number/operators/uint8.d.mts +24 -0
  311. package/dist/number/operators/uint8.d.mts.map +1 -0
  312. package/dist/number/operators/uint8.mjs +8 -0
  313. package/dist/number/operators/uint8.mjs.map +1 -0
  314. package/dist/number/refined-number-utils.d.mts +2 -2
  315. package/dist/number/refined-number-utils.d.mts.map +1 -1
  316. package/dist/number/refined-number-utils.mjs +1 -1
  317. package/dist/number/refined-number-utils.mjs.map +1 -1
  318. package/dist/object/object.mjs +1 -1
  319. package/dist/object/object.mjs.map +1 -1
  320. package/dist/others/fast-deep-equal.mjs +1 -1
  321. package/dist/others/fast-deep-equal.mjs.map +1 -1
  322. package/package.json +22 -9
  323. package/src/array/impl/array-utils-reducing-value.mts +4 -3
  324. package/src/array/impl/array-utils-shape-invariants.test.mts +1 -1
  325. package/src/array/impl/array-utils-slice-clamped.mts +1 -1
  326. package/src/array/impl/array-utils-slicing.mts +12 -3
  327. package/src/array/impl/array-utils-transformation.mts +6 -2
  328. package/src/array/impl/array-utils-validation.mts +2 -1
  329. package/src/built-in-tag.mts +59 -0
  330. package/src/built-in-tag.test.mts +215 -0
  331. package/src/collections/stack.mts +3 -3
  332. package/src/iterator/range.mts +10 -2
  333. package/src/iterator/range.test.mts +7 -0
  334. package/src/number/branded-types/finite-number.mts +23 -25
  335. package/src/number/branded-types/int.mts +20 -26
  336. package/src/number/branded-types/int16.mts +21 -26
  337. package/src/number/branded-types/int32.mts +21 -26
  338. package/src/number/branded-types/negative-finite-number.mts +25 -26
  339. package/src/number/branded-types/negative-int.mts +20 -27
  340. package/src/number/branded-types/negative-safe-int.mts +23 -28
  341. package/src/number/branded-types/non-negative-finite-number.mts +24 -25
  342. package/src/number/branded-types/non-negative-int16.mts +23 -26
  343. package/src/number/branded-types/non-negative-int32.mts +23 -26
  344. package/src/number/branded-types/non-positive-finite-number.mts +24 -25
  345. package/src/number/branded-types/non-positive-int.mts +20 -26
  346. package/src/number/branded-types/non-positive-safe-int.mts +21 -26
  347. package/src/number/branded-types/non-zero-finite-number.mts +23 -25
  348. package/src/number/branded-types/non-zero-int.mts +19 -25
  349. package/src/number/branded-types/non-zero-int16.mts +27 -28
  350. package/src/number/branded-types/non-zero-int32.mts +27 -28
  351. package/src/number/branded-types/non-zero-safe-int.mts +25 -35
  352. package/src/number/branded-types/non-zero-uint16.mts +24 -28
  353. package/src/number/branded-types/non-zero-uint32.mts +24 -28
  354. package/src/number/branded-types/positive-finite-number.mts +25 -25
  355. package/src/number/branded-types/positive-int.mts +21 -26
  356. package/src/number/branded-types/positive-int16.mts +23 -26
  357. package/src/number/branded-types/positive-int32.mts +23 -26
  358. package/src/number/branded-types/positive-safe-int.mts +24 -31
  359. package/src/number/branded-types/positive-uint16.mts +23 -26
  360. package/src/number/branded-types/positive-uint32.mts +23 -26
  361. package/src/number/branded-types/safe-int.mts +22 -29
  362. package/src/number/branded-types/safe-uint.mts +21 -27
  363. package/src/number/branded-types/uint.mts +21 -26
  364. package/src/number/branded-types/uint16.mts +21 -26
  365. package/src/number/branded-types/uint32.mts +21 -26
  366. package/src/number/enum/int8.mts +40 -52
  367. package/src/number/enum/uint8.mts +40 -48
  368. package/src/number/index.mts +1 -1
  369. package/src/number/num/impl/index.mts +1 -0
  370. package/src/number/num/impl/num.mts +715 -0
  371. package/src/number/{num.test.mts → num/impl/num.test.mts} +4 -4
  372. package/src/number/num/index.mts +16 -0
  373. package/src/number/num-arithmetic.test.mts +1 -1
  374. package/src/number/operators/finite-number.mts +20 -0
  375. package/src/number/operators/int.mts +20 -0
  376. package/src/number/operators/int16.mts +33 -0
  377. package/src/number/operators/int32.mts +33 -0
  378. package/src/number/operators/int8.mts +18 -0
  379. package/src/number/operators/negative-finite-number.mts +22 -0
  380. package/src/number/operators/negative-int.mts +22 -0
  381. package/src/number/operators/negative-safe-int.mts +32 -0
  382. package/src/number/operators/non-negative-finite-number.mts +32 -0
  383. package/src/number/operators/non-negative-int16.mts +33 -0
  384. package/src/number/operators/non-negative-int32.mts +33 -0
  385. package/src/number/operators/non-positive-finite-number.mts +21 -0
  386. package/src/number/operators/non-positive-int.mts +21 -0
  387. package/src/number/operators/non-positive-safe-int.mts +31 -0
  388. package/src/number/operators/non-zero-finite-number.mts +21 -0
  389. package/src/number/operators/non-zero-int.mts +22 -0
  390. package/src/number/operators/non-zero-int16.mts +32 -0
  391. package/src/number/operators/non-zero-int32.mts +32 -0
  392. package/src/number/operators/non-zero-safe-int.mts +34 -0
  393. package/src/number/operators/non-zero-uint16.mts +32 -0
  394. package/src/number/operators/non-zero-uint32.mts +32 -0
  395. package/src/number/operators/positive-finite-number.mts +32 -0
  396. package/src/number/operators/positive-int.mts +32 -0
  397. package/src/number/operators/positive-int16.mts +33 -0
  398. package/src/number/operators/positive-int32.mts +33 -0
  399. package/src/number/operators/positive-safe-int.mts +34 -0
  400. package/src/number/operators/positive-uint16.mts +33 -0
  401. package/src/number/operators/positive-uint32.mts +33 -0
  402. package/src/number/operators/safe-int.mts +35 -0
  403. package/src/number/operators/safe-uint.mts +33 -0
  404. package/src/number/operators/uint.mts +31 -0
  405. package/src/number/operators/uint16.mts +32 -0
  406. package/src/number/operators/uint32.mts +32 -0
  407. package/src/number/operators/uint8.mts +16 -0
  408. package/src/number/refined-number-utils.mts +4 -4
  409. package/src/object/object.mts +1 -1
  410. package/src/others/fast-deep-equal.mts +1 -1
  411. package/dist/number/num.d.mts +0 -550
  412. package/dist/number/num.d.mts.map +0 -1
  413. package/dist/number/num.mjs +0 -563
  414. package/dist/number/num.mjs.map +0 -1
  415. package/src/guard/is-error.test.mts +0 -145
  416. package/src/number/num.mts +0 -735
@@ -1,735 +0,0 @@
1
- import { SafeNumber } from 'ts-std-forge';
2
- import type {
3
- Decrement,
4
- FiniteNumber,
5
- Increment,
6
- Index,
7
- Int,
8
- Min,
9
- NaNType,
10
- NegativeIndex,
11
- NonNegativeNumber,
12
- NonZeroNumber,
13
- PositiveNumber,
14
- PositiveSafeIntWithSmallInt,
15
- RelaxedExclude,
16
- SmallInt,
17
- SmallUint,
18
- UnknownBrand,
19
- } from 'ts-type-forge';
20
- import { expectType } from '../expect-type.mjs';
21
- import { Result } from '../functional/index.mjs';
22
- import type { SmallPositiveInt } from '../types.mjs';
23
- import type {
24
- AddResult,
25
- DivIntResult,
26
- DivResult,
27
- MulResult,
28
- SubResult,
29
- } from './num-arithmetic-types.mjs';
30
-
31
- /**
32
- * Namespace providing utility functions for number manipulation and validation.
33
- *
34
- * This namespace offers a comprehensive set of type-safe number utilities
35
- * including:
36
- *
37
- * - Type conversion and validation
38
- * - Type guards for numeric constraints (non-zero, non-negative, positive)
39
- * - Range checking and clamping operations
40
- * - Mathematical operations with type safety
41
- * - Rounding utilities
42
- *
43
- * Many functions in this namespace leverage TypeScript's type system to provide
44
- * compile-time guarantees about numeric constraints.
45
- */
46
- export namespace Num {
47
- /**
48
- * Converts an unknown value to a number. Alias for the `Number` constructor.
49
- *
50
- * @example
51
- *
52
- * ```ts
53
- * const input = '123.45';
54
- *
55
- * const result = Num.from(input);
56
- *
57
- * assert.isTrue(result === 123.45);
58
- * ```
59
- *
60
- * @param n The value to convert.
61
- * @returns The numeric representation of `n`.
62
- */
63
- export const from: (n: unknown) => number = Number;
64
-
65
- /**
66
- * Safely parses a base-10 integer from a string, returning a {@link Result}
67
- * that is `Ok<Int>` for valid input and `Err<Error>` otherwise.
68
- *
69
- * This is a stricter alternative to both `parseInt` and `Number`:
70
- *
71
- * - Unlike `parseInt('12abc', 10)` (which returns `12`), trailing
72
- * non-numeric characters make the whole input invalid and yield `Err`.
73
- * - Unlike `Number('')` / `Number(' ')` (which return `0`), empty or
74
- * whitespace-only input yields `Err`.
75
- *
76
- * The empty-string case is rejected by delegating to `parseInt` (which
77
- * returns `NaN` there) rather than hard-coding a check, while the trailing-
78
- * garbage case is rejected via `Number`. Valid input is truncated toward
79
- * zero, so `'12.9'` becomes `12` and `'-3.5'` becomes `-3`.
80
- *
81
- * Only base 10 is supported. Use `Result.unwrapOk` (optionally with a
82
- * `?? Number.NaN` fallback) or `Result.unwrapOkOr` to get a plain number
83
- * back.
84
- *
85
- * @example
86
- *
87
- * ```ts
88
- * assert.strictEqual(
89
- * Result.unwrapOkOr(Num.safeParseInt('123'), Number.NaN),
90
- * 123,
91
- * );
92
- *
93
- * assert.strictEqual(
94
- * Result.unwrapOkOr(Num.safeParseInt('12.9'), Number.NaN),
95
- * 12,
96
- * );
97
- *
98
- * assert.strictEqual(
99
- * Result.unwrapOkOr(Num.safeParseInt('-12.9'), Number.NaN),
100
- * -12,
101
- * );
102
- *
103
- * assert.strictEqual(Number.parseInt('-12.9', 10), -12);
104
- *
105
- * // Native `parseInt` ignores trailing non-numeric characters
106
- *
107
- * assert.strictEqual(Number.parseInt('123abc', 10), 123);
108
- *
109
- * assert.isTrue(Number.isNaN(Number('123abc')));
110
- *
111
- * assert.isTrue(Result.isErr(Num.safeParseInt('123abc')));
112
- *
113
- * // Whitespace is not a valid integer, so we return an error instead of coercing to 0.
114
- *
115
- * assert.isTrue(Number.isNaN(Number.parseInt(' ', 10)));
116
- *
117
- * assert.strictEqual(Number(' '), 0); // Native `Number` coerces whitespace to 0
118
- *
119
- * assert.isTrue(Result.isErr(Num.safeParseInt('')));
120
- *
121
- * assert.strictEqual(Result.unwrapOk(Num.safeParseInt(' ')), undefined);
122
- *
123
- * // A value that overflows to Infinity is not an integer either, even though
124
- * // native `parseInt` reads a 1 out of it.
125
- *
126
- * assert.strictEqual(Number.parseInt('1e400', 10), 1);
127
- *
128
- * assert.isTrue(Result.isErr(Num.safeParseInt('1e400')));
129
- * ```
130
- *
131
- * @param s The string to parse.
132
- * @returns `Result.ok(parsedInt)` for valid input, otherwise `Result.err`
133
- * wrapping an `Error` describing the invalid input. A value that
134
- * overflows to `Infinity` is rejected, so the `Int` brand never lies.
135
- */
136
- export const safeParseInt = (s: string): Result<Int, Error> =>
137
- // The parsing itself is `SafeNumber.parseInteger` (Sumi D-49 (c)): one
138
- // implementation, in the package that owns the standard-library boundary.
139
- // What stays here is this function's own contract — the `Int` brand on the
140
- // success side, and an `Error` rather than a tagged record on the failure
141
- // side.
142
- Result.match(SafeNumber.parseInteger(s), {
143
- // eslint-disable-next-line total-functions/no-unsafe-type-assertion
144
- ok: (n) => Result.ok(n as Int),
145
- err: () =>
146
- Result.err(
147
- new Error(`safeParseInt: "${s}" is not a valid base-10 integer`),
148
- ),
149
- });
150
-
151
- /**
152
- * Safely parses a finite floating-point number from a string, returning a
153
- * {@link Result} that is `Ok<FiniteNumber>` for valid input and `Err<Error>`
154
- * otherwise.
155
- *
156
- * This is a stricter alternative to both `parseFloat` and `Number`:
157
- *
158
- * - Unlike `parseFloat('12abc')` (which returns `12`), trailing non-numeric
159
- * characters make the whole input invalid and yield `Err`.
160
- * - Unlike `Number('')` / `Number(' ')` (which return `0`), empty or
161
- * whitespace-only input yields `Err`.
162
- * - Unlike `Number('Infinity')` (which returns `Infinity`), non-finite values
163
- * yield `Err`.
164
- *
165
- * The empty-string case is rejected by delegating to `parseFloat` (which
166
- * returns `NaN` there) rather than hard-coding a check, while the trailing-
167
- * garbage case is rejected via `Number`. Decimal values are preserved as-is,
168
- * so `'12.9'` stays `12.9`.
169
- *
170
- * Use `Result.unwrapOk` (optionally with a `?? Number.NaN` fallback) or
171
- * `Result.unwrapOkOr` to get a plain number back.
172
- *
173
- * @example
174
- *
175
- * ```ts
176
- * assert.strictEqual(
177
- * Result.unwrapOkOr(Num.safeParseFloat('12.9'), Number.NaN),
178
- * 12.9,
179
- * );
180
- *
181
- * assert.strictEqual(
182
- * Result.unwrapOkOr(Num.safeParseFloat('-3.5'), Number.NaN),
183
- * -3.5,
184
- * );
185
- *
186
- * assert.strictEqual(
187
- * Result.unwrapOkOr(Num.safeParseFloat('1e3'), Number.NaN),
188
- * 1000,
189
- * );
190
- *
191
- * // Native `parseFloat` ignores trailing non-numeric characters
192
- *
193
- * assert.strictEqual(Number.parseFloat('12px'), 12);
194
- *
195
- * assert.isTrue(Result.isErr(Num.safeParseFloat('12px')));
196
- *
197
- * // Whitespace is not a valid number, so we return an error instead of coercing to 0.
198
- *
199
- * assert.isTrue(Result.isErr(Num.safeParseFloat('')));
200
- *
201
- * assert.isTrue(Result.isErr(Num.safeParseFloat(' ')));
202
- *
203
- * // Infinity and NaN are not finite, so they are rejected.
204
- *
205
- * assert.isTrue(Result.isErr(Num.safeParseFloat('Infinity')));
206
- *
207
- * assert.isTrue(Result.isErr(Num.safeParseFloat('NaN')));
208
- * ```
209
- *
210
- * @param s The string to parse.
211
- * @returns `Result.ok(parsedFloat)` for valid finite input, otherwise
212
- * `Result.err` wrapping an `Error` describing the invalid input.
213
- */
214
- export const safeParseFloat = (s: string): Result<FiniteNumber, Error> =>
215
- // The parsing itself is `SafeNumber.parse` (Sumi D-49 (c)): one
216
- // implementation, in the package that owns the standard-library boundary.
217
- // What stays here is this function's own contract — the `FiniteNumber`
218
- // brand on the success side, and an `Error` rather than a tagged record on
219
- // the failure side.
220
- Result.match(SafeNumber.parse(s), {
221
- // eslint-disable-next-line total-functions/no-unsafe-type-assertion
222
- ok: (n) => Result.ok(n as FiniteNumber),
223
- err: () =>
224
- Result.err(
225
- new Error(`safeParseFloat: "${s}" is not a valid finite number`),
226
- ),
227
- });
228
-
229
- /**
230
- * Type guard that checks if a number is non-zero.
231
- *
232
- * When this function returns `true`, TypeScript narrows the type to exclude
233
- * zero, providing compile-time safety for division operations and other
234
- * calculations that require non-zero values.
235
- *
236
- * @example
237
- *
238
- * ```ts
239
- * const value: number = 5;
240
- *
241
- * if (Num.isNonZero(value)) {
242
- * // Safe to divide now that we know value is non-zero
243
- * // eslint-disable-next-line total-functions/no-partial-division
244
- * const inverted = 1 / value;
245
- *
246
- * assert.isTrue(inverted === 0.2);
247
- * }
248
- *
249
- * assert.isFalse(Num.isNonZero(0));
250
- * ```
251
- *
252
- * @template N - The numeric literal type or number type to check
253
- * @param num - The number to check
254
- * @returns `true` if the number is not zero, `false` otherwise
255
- */
256
- export const isNonZero = <N extends number>(
257
- num: N,
258
- ): num is NonZeroNumber & RelaxedExclude<N, 0> => num !== 0;
259
-
260
- expectType<NonZeroNumber & RelaxedExclude<123, 0>, UnknownBrand>('<=');
261
-
262
- /**
263
- * Type guard that checks if a number is non-negative (greater than or equal
264
- * to zero).
265
- *
266
- * When this function returns `true`, TypeScript narrows the type to exclude
267
- * negative values, which is useful for operations that require non-negative
268
- * inputs like array indices or measurements.
269
- *
270
- * @example
271
- *
272
- * ```ts
273
- * const candidate = 10;
274
- *
275
- * if (Num.isNonNegative(candidate)) {
276
- * const index: number = candidate;
277
- *
278
- * assert.isTrue(index === 10);
279
- * }
280
- *
281
- * assert.isFalse(Num.isNonNegative(-1));
282
- * ```
283
- *
284
- * @template N - The numeric literal type or number type to check
285
- * @param num - The number to check
286
- * @returns `true` if the number is >= 0, `false` otherwise
287
- */
288
- export const isNonNegative = <N extends number>(
289
- num: N,
290
- ): num is NonNegativeNumber & RelaxedExclude<N, NegativeIndex<1024>> =>
291
- num >= 0;
292
-
293
- /**
294
- * Type guard that checks if a number is positive (greater than zero).
295
- *
296
- * When this function returns `true`, TypeScript narrows the type to exclude
297
- * zero and negative values. This is particularly useful for validating inputs
298
- * that must be strictly positive, such as dimensions, counts, or rates.
299
- *
300
- * @example
301
- *
302
- * ```ts
303
- * const amount = 42;
304
- *
305
- * if (Num.isPositive(amount)) {
306
- * assert.isTrue(amount > 0);
307
- * }
308
- *
309
- * assert.isFalse(Num.isPositive(0));
310
- * ```
311
- *
312
- * @template N - The numeric literal type or number type to check
313
- * @param num - The number to check
314
- * @returns `true` if the number is > 0, `false` otherwise
315
- */
316
- export const isPositive = <N extends number>(
317
- num: N,
318
- ): num is PositiveNumber & RelaxedExclude<N, NegativeIndex<1024> | 0> =>
319
- num > 0;
320
-
321
- /**
322
- * Creates a function that checks if a number `x` is within the range
323
- * `lowerBound <= x < upperBound`.
324
- *
325
- * @example
326
- *
327
- * ```ts
328
- * const isGrade = Num.isInRange(0, 100);
329
- *
330
- * assert.isTrue(isGrade(50));
331
- *
332
- * assert.isFalse(isGrade(100));
333
- * ```
334
- *
335
- * @param lowerBound The lower bound (inclusive).
336
- * @param upperBound The upper bound (exclusive).
337
- * @returns A function that takes a number `x` and returns `true` if `x` is in
338
- * the range, `false` otherwise.
339
- */
340
- export const isInRange =
341
- (lowerBound: number, upperBound: number) =>
342
- (x: number): boolean =>
343
- lowerBound <= x && x < upperBound;
344
-
345
- /**
346
- * Creates a function that checks if a number `x` is within the range
347
- * `lowerBound <= x <= upperBound`.
348
- *
349
- * @example
350
- *
351
- * ```ts
352
- * const isPercentage = Num.isInRangeInclusive(0, 100);
353
- *
354
- * assert.isTrue(isPercentage(100));
355
- *
356
- * assert.isFalse(isPercentage(-1));
357
- * ```
358
- *
359
- * @param lowerBound The lower bound (inclusive).
360
- * @param upperBound The upper bound (inclusive).
361
- * @returns A function that takes a number `x` and returns `true` if `x` is in
362
- * the range, `false` otherwise.
363
- */
364
- export const isInRangeInclusive =
365
- (lowerBound: number, upperBound: number) =>
366
- (x: number): boolean =>
367
- lowerBound <= x && x <= upperBound;
368
-
369
- /**
370
- * @template N - A SmallUint representing the exclusive upper bound
371
- * @internal
372
- * Helper type mapping each SmallUint N to the union of integers from 0 to N-1.
373
- * Used internally for type-safe range operations.
374
- *
375
- * For example:
376
- * - LT[3] = 0 | 1 | 2
377
- * - LT[5] = 0 | 1 | 2 | 3 | 4
378
- */
379
- type LT = Readonly<{ [N in SmallUint]: Index<N> }>;
380
-
381
- /**
382
- * @template N - A SmallUint representing the inclusive upper bound
383
- * @internal
384
- * Helper type mapping each SmallUint N to the union of integers from 0 to N (inclusive).
385
- * Used internally for type-safe range operations with inclusive upper bounds.
386
- *
387
- * For example:
388
- * - LEQ[3] = 0 | 1 | 2 | 3
389
- * - LEQ[5] = 0 | 1 | 2 | 3 | 4 | 5
390
- */
391
- type LEQ = Readonly<{ [N in SmallUint]: Index<N> | N }>;
392
-
393
- /**
394
- * Creates a type guard that checks if a number is an unsigned integer within
395
- * a specified range.
396
- *
397
- * This function returns a predicate that validates whether a number is:
398
- *
399
- * - A safe integer (no floating point)
400
- * - Within the range [lowerBound, upperBound)
401
- *
402
- * The returned type guard provides precise type narrowing when the bounds are
403
- * SmallUint literals, making it ideal for array index validation.
404
- *
405
- * @example
406
- *
407
- * ```ts
408
- * const indexGuard = Num.isUintInRange(0, 5);
409
- *
410
- * assert.isTrue(indexGuard(3));
411
- *
412
- * assert.isFalse(indexGuard(5));
413
- *
414
- * assert.isFalse(indexGuard(-1));
415
- * ```
416
- *
417
- * @template L - The lower bound as a SmallUint literal type
418
- * @template U - The upper bound as a SmallUint literal type
419
- * @param lowerBound - The minimum value (inclusive)
420
- * @param upperBound - The maximum value (exclusive)
421
- * @returns A type guard function that validates and narrows number types
422
- */
423
- export const isUintInRange =
424
- <L extends SmallUint, U extends SmallUint>(lowerBound: L, upperBound: U) =>
425
- (x: number): x is RelaxedExclude<LT[U], LT[Min<L>]> =>
426
- Number.isSafeInteger(x) && lowerBound <= x && x < upperBound;
427
-
428
- /**
429
- * Creates a type guard that checks if a number is an unsigned integer within
430
- * a specified inclusive range.
431
- *
432
- * This function returns a predicate that validates whether a number is:
433
- *
434
- * - A safe integer (no floating point)
435
- * - Within the range [lowerBound, upperBound] (both bounds inclusive)
436
- *
437
- * The returned type guard provides precise type narrowing when the bounds are
438
- * SmallUint literals, useful for validating scores, percentages, or other
439
- * bounded values.
440
- *
441
- * @example
442
- *
443
- * ```ts
444
- * const inclusiveGuard = Num.isUintInRangeInclusive(0, 5);
445
- *
446
- * assert.isTrue(inclusiveGuard(5));
447
- *
448
- * assert.isFalse(inclusiveGuard(6));
449
- * ```
450
- *
451
- * @template L - The lower bound as a SmallUint literal type
452
- * @template U - The upper bound as a SmallUint literal type
453
- * @param lowerBound - The minimum value (inclusive)
454
- * @param upperBound - The maximum value (inclusive)
455
- * @returns A type guard function that validates and narrows number types
456
- */
457
- export const isUintInRangeInclusive =
458
- <L extends SmallUint, U extends SmallUint>(lowerBound: L, upperBound: U) =>
459
- (x: number): x is RelaxedExclude<LEQ[U], LT[Min<L>]> =>
460
- Number.isSafeInteger(x) && lowerBound <= x && x <= upperBound;
461
-
462
- /**
463
- * Clamps a value within the given range. If the target value is invalid (not
464
- * finite), returns the lower bound.
465
- *
466
- * Provides two usage patterns for maximum flexibility:
467
- *
468
- * - **Direct usage**: Pass all three arguments to get the clamped value
469
- * immediately
470
- * - **Curried usage**: Pass bounds to get a reusable clamping function
471
- *
472
- * @example
473
- *
474
- * ```ts
475
- * assert.isTrue(Num.clamp(150, 0, 100) === 100);
476
- *
477
- * assert.isTrue(Num.clamp(-50, 0, 100) === 0);
478
- *
479
- * const clampToPercentage = Num.clamp(0, 100);
480
- *
481
- * assert.isTrue(clampToPercentage(75) === 75);
482
- *
483
- * assert.isTrue(clampToPercentage(150) === 100);
484
- * ```
485
- */
486
- export function clamp(
487
- target: number,
488
- lowerBound: number,
489
- upperBound: number,
490
- ): number;
491
-
492
- // Curried version
493
- export function clamp(
494
- lowerBound: number,
495
- upperBound: number,
496
- ): (target: number) => number;
497
-
498
- export function clamp(
499
- ...args:
500
- | readonly [target: number, lowerBound: number, upperBound: number]
501
- | readonly [lowerBound: number, upperBound: number]
502
- ): number | ((target: number) => number) {
503
- switch (args.length) {
504
- case 3: {
505
- const [target, lowerBound, upperBound] = args;
506
-
507
- return !Number.isFinite(target)
508
- ? lowerBound
509
- : Math.max(lowerBound, Math.min(upperBound, target));
510
- }
511
-
512
- case 2: {
513
- const [lowerBound, upperBound] = args;
514
-
515
- return (target: number): number =>
516
- clamp(target, lowerBound, upperBound);
517
- }
518
- }
519
- }
520
-
521
- /**
522
- * Adds two numbers, returning the tightest sound branded result type.
523
- *
524
- * The sign of the result is computed exactly (e.g. a non-negative plus a
525
- * non-negative is non-negative); the integer/finite level is preserved, with
526
- * `SafeInt` operands widening to `Int` because the sum may exceed the safe
527
- * range. No clamping is performed — for a result that stays inside a bounded
528
- * type, use that type's branded `add` instead.
529
- *
530
- * @param a - The first addend.
531
- * @param b - The second addend.
532
- * @returns `a + b`, typed as the tightest branded type guaranteed to contain
533
- * it.
534
- */
535
- export const add = <A extends number, B extends number>(
536
- a: A,
537
- b: B,
538
- ): AddResult<A, B> =>
539
- // eslint-disable-next-line total-functions/no-unsafe-type-assertion
540
- (a + b) as AddResult<A, B>;
541
-
542
- /**
543
- * Subtracts `b` from `a`, returning the tightest sound branded result type.
544
- *
545
- * The sign is computed exactly; the level is preserved (with `SafeInt`
546
- * widening to `Int`). No clamping — for saturating subtraction that stays in a
547
- * bounded type (e.g. `Uint.sub` clamping at `0`), use that type's branded
548
- * `sub`.
549
- *
550
- * @param a - The minuend.
551
- * @param b - The subtrahend.
552
- * @returns `a - b`, typed as the tightest branded type guaranteed to contain
553
- * it.
554
- */
555
- export const sub = <A extends number, B extends number>(
556
- a: A,
557
- b: B,
558
- ): SubResult<A, B> =>
559
- // eslint-disable-next-line total-functions/no-unsafe-type-assertion
560
- (a - b) as SubResult<A, B>;
561
-
562
- /**
563
- * Multiplies two numbers, returning the tightest sound branded result type.
564
- *
565
- * The sign follows the usual product rule (e.g. negative times negative is
566
- * positive); the level is preserved (with `SafeInt` widening to `Int`). No
567
- * clamping.
568
- *
569
- * @param a - The first factor.
570
- * @param b - The second factor.
571
- * @returns `a * b`, typed as the tightest branded type guaranteed to contain
572
- * it.
573
- */
574
- export const mul = <A extends number, B extends number>(
575
- a: A,
576
- b: B,
577
- ): MulResult<A, B> =>
578
- // eslint-disable-next-line total-functions/no-unsafe-type-assertion
579
- (a * b) as MulResult<A, B>;
580
-
581
- /**
582
- * Performs type-safe exact division with a compile-time zero-check.
583
- *
584
- * The divisor must be typed as `NonZeroNumber` or a non-zero numeric literal.
585
- * The result sign follows the quotient rule; because exact division can be
586
- * fractional, the level is `finite` (or `number`).
587
- *
588
- * @param a - The dividend.
589
- * @param b - The divisor (must be non-zero, enforced by types).
590
- * @returns `a / b`, typed as the tightest branded type guaranteed to contain
591
- * it.
592
- */
593
- export const div = <
594
- A extends number,
595
- B extends NonZeroNumber | SmallInt<'!=0'>,
596
- >(
597
- a: A,
598
- b: B,
599
- ): DivResult<A, B> =>
600
- // eslint-disable-next-line total-functions/no-partial-division, total-functions/no-unsafe-type-assertion
601
- (a / b) as DivResult<A, B>;
602
-
603
- /**
604
- * Performs integer division using floor division.
605
- *
606
- * Computes `⌊⌊a⌋ / b⌋`: the dividend is floored, the divisor is used as is,
607
- * and the quotient is floored. For a positive integer divisor this is
608
- * `⌊a / b⌋`. The divisor is not floored, since a divisor in `(-1, 1)` would
609
- * floor to `0` or `-1`.
610
- *
611
- * Like `div`, the divisor must be typed as `NonZeroNumber` or a non-zero
612
- * numeric literal. A divisor of magnitude below `1` makes the quotient larger
613
- * than the dividend, so it overflows to `±Infinity` once `|a / b|` exceeds
614
- * `Number.MAX_VALUE` (e.g. `1e300 / 1e-10`), as `mul` can.
615
- *
616
- * @param a - The dividend
617
- * @param b - The divisor (must be non-zero, enforced by types)
618
- * @returns The integer quotient `⌊⌊a⌋ / b⌋`
619
- */
620
- export const divInt = <
621
- A extends number,
622
- B extends NonZeroNumber | SmallInt<'!=0'>,
623
- >(
624
- a: A,
625
- b: B,
626
- ): DivIntResult<A, B> => {
627
- // eslint-disable-next-line total-functions/no-partial-division
628
- const quotient = Math.floor(Math.floor(a) / b);
629
-
630
- // eslint-disable-next-line total-functions/no-unsafe-type-assertion
631
- return quotient as DivIntResult<A, B>;
632
- };
633
-
634
- /**
635
- * Rounds a number to a specified number of decimal places.
636
- *
637
- * Uses the standard rounding algorithm (round half up) to round the number to
638
- * the given precision. The precision must be a positive safe integer.
639
- *
640
- * @param num - The number to round
641
- * @param precision - The number of decimal places (must be positive)
642
- * @returns The rounded number
643
- */
644
- export const roundAt = (
645
- num: number,
646
- precision: PositiveSafeIntWithSmallInt,
647
- ): number => {
648
- const digit = 10 ** precision;
649
-
650
- // eslint-disable-next-line total-functions/no-partial-division
651
- return Math.round(num * digit) / digit;
652
- };
653
-
654
- /**
655
- * Rounds a number to the nearest integer using bitwise operations.
656
- *
657
- * This function uses a bitwise OR trick for potentially faster rounding.
658
- * Note: This implementation rounds half up for positive numbers but may
659
- * behave differently for negative numbers compared to Math.round.
660
- *
661
- * @param num - The number to round
662
- * @returns The rounded integer as an Int branded type
663
- */
664
- // eslint-disable-next-line total-functions/no-unsafe-type-assertion
665
- export const roundToInt = (num: number): Int => Math.trunc(num + 0.5) as Int;
666
-
667
- /**
668
- * Creates a reusable rounding function with a fixed precision.
669
- *
670
- * This is a curried version of roundAt that returns a function configured to
671
- * always round to the specified number of decimal places. Useful for creating
672
- * consistent rounding behavior across multiple values.
673
- *
674
- * @param digit - The number of decimal places for rounding
675
- * @returns A function that rounds numbers to the specified precision
676
- */
677
- export const round = (
678
- digit: PositiveSafeIntWithSmallInt,
679
- ): ((num: number) => number) => {
680
- const powAmount = 10 ** digit;
681
-
682
- return (target: number) =>
683
- // eslint-disable-next-line total-functions/no-partial-division
684
- roundToInt(powAmount * target) / powAmount;
685
- };
686
-
687
- /**
688
- * Converts NaN values to undefined while preserving all other numbers.
689
- *
690
- * This function is useful for handling potentially invalid numeric operations
691
- * in a type-safe way, converting NaN results to undefined for easier handling
692
- * with optional chaining or nullish coalescing.
693
- *
694
- * @template N - The numeric type (literal or number)
695
- * @param num - The number to check
696
- * @returns The original number if not NaN, otherwise undefined
697
- */
698
- export const mapNaN2Undefined = <N extends number>(
699
- num: N,
700
- ): RelaxedExclude<N, NaNType> | undefined =>
701
- Number.isNaN(num)
702
- ? undefined
703
- : // eslint-disable-next-line total-functions/no-unsafe-type-assertion
704
- (num as RelaxedExclude<N, NaNType>);
705
-
706
- /**
707
- * Type-safe increment operation for SmallUint values.
708
- *
709
- * Increments a SmallUint (0-40) by 1 with the result type computed at compile
710
- * time. This provides type-level arithmetic for small unsigned integers,
711
- * useful for type-safe counter operations.
712
- *
713
- * @template N - A SmallUint literal type (0-40)
714
- * @param n - The SmallUint value to increment
715
- * @returns The incremented value with type Increment<N>
716
- */
717
- export const increment = <N extends SmallUint>(n: N): Increment<N> =>
718
- // eslint-disable-next-line total-functions/no-unsafe-type-assertion
719
- (n + 1) as Increment<N>;
720
-
721
- /**
722
- * Type-safe decrement operation for positive SmallInt values.
723
- *
724
- * Decrements a positive SmallInt (1-40) by 1 with the result type computed at
725
- * compile time. This provides type-level arithmetic for small positive
726
- * integers, useful for type-safe countdown operations.
727
- *
728
- * @template N - A positive SmallInt literal type (1-40)
729
- * @param n - The positive SmallInt value to decrement
730
- * @returns The decremented value with type Decrement<N>
731
- */
732
- export const decrement = <N extends SmallPositiveInt>(n: N): Decrement<N> =>
733
- // eslint-disable-next-line total-functions/no-unsafe-type-assertion
734
- (n - 1) as Decrement<N>;
735
- }