ts-data-forge 11.0.0 → 12.0.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 (185) hide show
  1. package/README.md +2 -2
  2. package/dist/number/branded-types/finite-number.d.mts +47 -61
  3. package/dist/number/branded-types/finite-number.d.mts.map +1 -1
  4. package/dist/number/branded-types/finite-number.mjs +37 -41
  5. package/dist/number/branded-types/finite-number.mjs.map +1 -1
  6. package/dist/number/branded-types/int.d.mts +40 -46
  7. package/dist/number/branded-types/int.d.mts.map +1 -1
  8. package/dist/number/branded-types/int.mjs +29 -31
  9. package/dist/number/branded-types/int.mjs.map +1 -1
  10. package/dist/number/branded-types/int16.d.mts +71 -59
  11. package/dist/number/branded-types/int16.d.mts.map +1 -1
  12. package/dist/number/branded-types/int16.mjs +56 -47
  13. package/dist/number/branded-types/int16.mjs.map +1 -1
  14. package/dist/number/branded-types/int32.d.mts +71 -59
  15. package/dist/number/branded-types/int32.d.mts.map +1 -1
  16. package/dist/number/branded-types/int32.mjs +56 -47
  17. package/dist/number/branded-types/int32.mjs.map +1 -1
  18. package/dist/number/branded-types/negative-finite-number.d.mts +76 -60
  19. package/dist/number/branded-types/negative-finite-number.d.mts.map +1 -1
  20. package/dist/number/branded-types/negative-finite-number.mjs +62 -49
  21. package/dist/number/branded-types/negative-finite-number.mjs.map +1 -1
  22. package/dist/number/branded-types/negative-int.d.mts +66 -49
  23. package/dist/number/branded-types/negative-int.d.mts.map +1 -1
  24. package/dist/number/branded-types/negative-int.mjs +48 -39
  25. package/dist/number/branded-types/negative-int.mjs.map +1 -1
  26. package/dist/number/branded-types/negative-safe-int.d.mts +64 -57
  27. package/dist/number/branded-types/negative-safe-int.d.mts.map +1 -1
  28. package/dist/number/branded-types/negative-safe-int.mjs +49 -44
  29. package/dist/number/branded-types/negative-safe-int.mjs.map +1 -1
  30. package/dist/number/branded-types/non-negative-finite-number.d.mts +80 -65
  31. package/dist/number/branded-types/non-negative-finite-number.d.mts.map +1 -1
  32. package/dist/number/branded-types/non-negative-finite-number.mjs +65 -53
  33. package/dist/number/branded-types/non-negative-finite-number.mjs.map +1 -1
  34. package/dist/number/branded-types/non-negative-int16.d.mts +71 -58
  35. package/dist/number/branded-types/non-negative-int16.d.mts.map +1 -1
  36. package/dist/number/branded-types/non-negative-int16.mjs +55 -45
  37. package/dist/number/branded-types/non-negative-int16.mjs.map +1 -1
  38. package/dist/number/branded-types/non-negative-int32.d.mts +71 -59
  39. package/dist/number/branded-types/non-negative-int32.d.mts.map +1 -1
  40. package/dist/number/branded-types/non-negative-int32.mjs +55 -46
  41. package/dist/number/branded-types/non-negative-int32.mjs.map +1 -1
  42. package/dist/number/branded-types/non-positive-finite-number.d.mts +70 -55
  43. package/dist/number/branded-types/non-positive-finite-number.d.mts.map +1 -1
  44. package/dist/number/branded-types/non-positive-finite-number.mjs +55 -43
  45. package/dist/number/branded-types/non-positive-finite-number.mjs.map +1 -1
  46. package/dist/number/branded-types/non-positive-int.d.mts +46 -146
  47. package/dist/number/branded-types/non-positive-int.d.mts.map +1 -1
  48. package/dist/number/branded-types/non-positive-int.mjs +33 -108
  49. package/dist/number/branded-types/non-positive-int.mjs.map +1 -1
  50. package/dist/number/branded-types/non-positive-safe-int.d.mts +62 -54
  51. package/dist/number/branded-types/non-positive-safe-int.d.mts.map +1 -1
  52. package/dist/number/branded-types/non-positive-safe-int.mjs +46 -41
  53. package/dist/number/branded-types/non-positive-safe-int.mjs.map +1 -1
  54. package/dist/number/branded-types/non-zero-finite-number.d.mts +62 -49
  55. package/dist/number/branded-types/non-zero-finite-number.d.mts.map +1 -1
  56. package/dist/number/branded-types/non-zero-finite-number.mjs +46 -37
  57. package/dist/number/branded-types/non-zero-finite-number.mjs.map +1 -1
  58. package/dist/number/branded-types/non-zero-int.d.mts +51 -38
  59. package/dist/number/branded-types/non-zero-int.d.mts.map +1 -1
  60. package/dist/number/branded-types/non-zero-int.mjs +31 -27
  61. package/dist/number/branded-types/non-zero-int.mjs.map +1 -1
  62. package/dist/number/branded-types/non-zero-int16.d.mts +59 -54
  63. package/dist/number/branded-types/non-zero-int16.d.mts.map +1 -1
  64. package/dist/number/branded-types/non-zero-int16.mjs +44 -41
  65. package/dist/number/branded-types/non-zero-int16.mjs.map +1 -1
  66. package/dist/number/branded-types/non-zero-int32.d.mts +59 -55
  67. package/dist/number/branded-types/non-zero-int32.d.mts.map +1 -1
  68. package/dist/number/branded-types/non-zero-int32.mjs +44 -42
  69. package/dist/number/branded-types/non-zero-int32.mjs.map +1 -1
  70. package/dist/number/branded-types/non-zero-safe-int.d.mts +60 -55
  71. package/dist/number/branded-types/non-zero-safe-int.d.mts.map +1 -1
  72. package/dist/number/branded-types/non-zero-safe-int.mjs +44 -42
  73. package/dist/number/branded-types/non-zero-safe-int.mjs.map +1 -1
  74. package/dist/number/branded-types/non-zero-uint16.d.mts +59 -54
  75. package/dist/number/branded-types/non-zero-uint16.d.mts.map +1 -1
  76. package/dist/number/branded-types/non-zero-uint16.mjs +43 -41
  77. package/dist/number/branded-types/non-zero-uint16.mjs.map +1 -1
  78. package/dist/number/branded-types/non-zero-uint32.d.mts +59 -54
  79. package/dist/number/branded-types/non-zero-uint32.d.mts.map +1 -1
  80. package/dist/number/branded-types/non-zero-uint32.mjs +43 -41
  81. package/dist/number/branded-types/non-zero-uint32.mjs.map +1 -1
  82. package/dist/number/branded-types/positive-finite-number.d.mts +82 -64
  83. package/dist/number/branded-types/positive-finite-number.d.mts.map +1 -1
  84. package/dist/number/branded-types/positive-finite-number.mjs +67 -52
  85. package/dist/number/branded-types/positive-finite-number.mjs.map +1 -1
  86. package/dist/number/branded-types/positive-int.d.mts +53 -70
  87. package/dist/number/branded-types/positive-int.d.mts.map +1 -1
  88. package/dist/number/branded-types/positive-int.mjs +42 -52
  89. package/dist/number/branded-types/positive-int.mjs.map +1 -1
  90. package/dist/number/branded-types/positive-int16.d.mts +68 -58
  91. package/dist/number/branded-types/positive-int16.d.mts.map +1 -1
  92. package/dist/number/branded-types/positive-int16.mjs +52 -45
  93. package/dist/number/branded-types/positive-int16.mjs.map +1 -1
  94. package/dist/number/branded-types/positive-int32.d.mts +68 -58
  95. package/dist/number/branded-types/positive-int32.d.mts.map +1 -1
  96. package/dist/number/branded-types/positive-int32.mjs +52 -45
  97. package/dist/number/branded-types/positive-int32.mjs.map +1 -1
  98. package/dist/number/branded-types/positive-safe-int.d.mts +72 -61
  99. package/dist/number/branded-types/positive-safe-int.d.mts.map +1 -1
  100. package/dist/number/branded-types/positive-safe-int.mjs +56 -48
  101. package/dist/number/branded-types/positive-safe-int.mjs.map +1 -1
  102. package/dist/number/branded-types/positive-uint16.d.mts +68 -58
  103. package/dist/number/branded-types/positive-uint16.d.mts.map +1 -1
  104. package/dist/number/branded-types/positive-uint16.mjs +52 -45
  105. package/dist/number/branded-types/positive-uint16.mjs.map +1 -1
  106. package/dist/number/branded-types/positive-uint32.d.mts +68 -59
  107. package/dist/number/branded-types/positive-uint32.d.mts.map +1 -1
  108. package/dist/number/branded-types/positive-uint32.mjs +52 -46
  109. package/dist/number/branded-types/positive-uint32.mjs.map +1 -1
  110. package/dist/number/branded-types/safe-int.d.mts +52 -66
  111. package/dist/number/branded-types/safe-int.d.mts.map +1 -1
  112. package/dist/number/branded-types/safe-int.mjs +45 -47
  113. package/dist/number/branded-types/safe-int.mjs.map +1 -1
  114. package/dist/number/branded-types/safe-uint.d.mts +68 -58
  115. package/dist/number/branded-types/safe-uint.d.mts.map +1 -1
  116. package/dist/number/branded-types/safe-uint.mjs +53 -46
  117. package/dist/number/branded-types/safe-uint.mjs.map +1 -1
  118. package/dist/number/branded-types/uint.d.mts +72 -55
  119. package/dist/number/branded-types/uint.d.mts.map +1 -1
  120. package/dist/number/branded-types/uint.mjs +52 -45
  121. package/dist/number/branded-types/uint.mjs.map +1 -1
  122. package/dist/number/branded-types/uint16.d.mts +66 -59
  123. package/dist/number/branded-types/uint16.d.mts.map +1 -1
  124. package/dist/number/branded-types/uint16.mjs +51 -45
  125. package/dist/number/branded-types/uint16.mjs.map +1 -1
  126. package/dist/number/branded-types/uint32.d.mts +66 -57
  127. package/dist/number/branded-types/uint32.d.mts.map +1 -1
  128. package/dist/number/branded-types/uint32.mjs +50 -45
  129. package/dist/number/branded-types/uint32.mjs.map +1 -1
  130. package/dist/number/enum/int8.d.mts +62 -66
  131. package/dist/number/enum/int8.d.mts.map +1 -1
  132. package/dist/number/enum/int8.mjs +57 -51
  133. package/dist/number/enum/int8.mjs.map +1 -1
  134. package/dist/number/enum/uint8.d.mts +66 -59
  135. package/dist/number/enum/uint8.d.mts.map +1 -1
  136. package/dist/number/enum/uint8.mjs +57 -51
  137. package/dist/number/enum/uint8.mjs.map +1 -1
  138. package/dist/number/refined-number-utils.d.mts +9 -9
  139. package/dist/number/refined-number-utils.d.mts.map +1 -1
  140. package/dist/number/refined-number-utils.mjs +7 -7
  141. package/dist/number/refined-number-utils.mjs.map +1 -1
  142. package/package.json +2 -1
  143. package/src/number/branded-types/finite-number.mts +47 -61
  144. package/src/number/branded-types/int.mts +40 -46
  145. package/src/number/branded-types/int16.mts +72 -60
  146. package/src/number/branded-types/int32.mts +72 -60
  147. package/src/number/branded-types/negative-finite-number.mts +78 -71
  148. package/src/number/branded-types/negative-finite-number.test.mts +4 -4
  149. package/src/number/branded-types/negative-int.mts +68 -60
  150. package/src/number/branded-types/negative-int.test.mts +5 -5
  151. package/src/number/branded-types/negative-safe-int.mts +66 -68
  152. package/src/number/branded-types/negative-safe-int.test.mts +4 -4
  153. package/src/number/branded-types/non-negative-finite-number.mts +81 -66
  154. package/src/number/branded-types/non-negative-int16.mts +72 -59
  155. package/src/number/branded-types/non-negative-int32.mts +72 -60
  156. package/src/number/branded-types/non-positive-finite-number.mts +71 -56
  157. package/src/number/branded-types/non-positive-finite-number.test.mts +7 -7
  158. package/src/number/branded-types/non-positive-int.mts +47 -147
  159. package/src/number/branded-types/non-positive-int.test.mts +7 -7
  160. package/src/number/branded-types/non-positive-safe-int.mts +63 -55
  161. package/src/number/branded-types/non-positive-safe-int.test.mts +7 -7
  162. package/src/number/branded-types/non-zero-finite-number.mts +62 -51
  163. package/src/number/branded-types/non-zero-int.mts +51 -38
  164. package/src/number/branded-types/non-zero-int16.mts +60 -55
  165. package/src/number/branded-types/non-zero-int32.mts +60 -56
  166. package/src/number/branded-types/non-zero-safe-int.mts +61 -56
  167. package/src/number/branded-types/non-zero-uint16.mts +60 -55
  168. package/src/number/branded-types/non-zero-uint32.mts +60 -55
  169. package/src/number/branded-types/positive-finite-number.mts +83 -65
  170. package/src/number/branded-types/positive-int.mts +54 -71
  171. package/src/number/branded-types/positive-int16.mts +69 -59
  172. package/src/number/branded-types/positive-int32.mts +69 -59
  173. package/src/number/branded-types/positive-safe-int.mts +73 -62
  174. package/src/number/branded-types/positive-uint16.mts +69 -59
  175. package/src/number/branded-types/positive-uint32.mts +69 -60
  176. package/src/number/branded-types/safe-int.mts +53 -67
  177. package/src/number/branded-types/safe-uint.mts +69 -59
  178. package/src/number/branded-types/uint.mts +73 -56
  179. package/src/number/branded-types/uint16.mts +67 -60
  180. package/src/number/branded-types/uint32.mts +67 -58
  181. package/src/number/enum/int8.mts +70 -73
  182. package/src/number/enum/int8.test.mts +7 -4
  183. package/src/number/enum/uint8.mts +74 -66
  184. package/src/number/enum/uint8.test.mts +7 -4
  185. package/src/number/refined-number-utils.mts +22 -19
@@ -139,23 +139,23 @@ describe('NonPositiveFiniteNumber test', () => {
139
139
  });
140
140
  });
141
141
 
142
- describe('NonPositiveFiniteNumber.clamp', () => {
142
+ describe('NonPositiveFiniteNumber.fromNumber', () => {
143
143
  test('returns the same value if within range', () => {
144
- expect(NonPositiveFiniteNumber.clamp(-5.5)).toBe(-5.5);
144
+ expect(NonPositiveFiniteNumber.fromNumber(-5.5)).toBe(-5.5);
145
145
 
146
- expect(NonPositiveFiniteNumber.clamp(0)).toBe(0);
146
+ expect(NonPositiveFiniteNumber.fromNumber(0)).toBe(0);
147
147
 
148
- expect(NonPositiveFiniteNumber.clamp(-1000.5)).toBe(-1000.5);
148
+ expect(NonPositiveFiniteNumber.fromNumber(-1000.5)).toBe(-1000.5);
149
149
  });
150
150
 
151
151
  test('clamps positive values to MAX_VALUE (0)', () => {
152
- expect(NonPositiveFiniteNumber.clamp(5.5)).toBe(0);
152
+ expect(NonPositiveFiniteNumber.fromNumber(5.5)).toBe(0);
153
153
 
154
- expect(NonPositiveFiniteNumber.clamp(1000)).toBe(0);
154
+ expect(NonPositiveFiniteNumber.fromNumber(1000)).toBe(0);
155
155
  });
156
156
 
157
157
  test('clamps -Infinity to the lower bound', () => {
158
- expect(NonPositiveFiniteNumber.clamp(Number.NEGATIVE_INFINITY)).toBe(
158
+ expect(NonPositiveFiniteNumber.fromNumber(Number.NEGATIVE_INFINITY)).toBe(
159
159
  -Number.MAX_VALUE,
160
160
  );
161
161
  });
@@ -11,7 +11,7 @@ const {
11
11
  MAX_VALUE,
12
12
  add,
13
13
  castType,
14
- clamp,
14
+ fromNumber,
15
15
  is,
16
16
  max: max_,
17
17
  min: min_,
@@ -32,19 +32,9 @@ const {
32
32
  /**
33
33
  * Type guard that checks if a value is a non-positive integer.
34
34
  *
35
- * A non-positive integer is any integer less than or equal to zero (<= 0).
36
- * This includes zero and all negative integers, but excludes positive numbers
37
- * and non-integers.
38
- *
39
- * @example
40
- *
41
- * ```ts
42
- * assert.isTrue(isNonPositiveInt(0));
43
- *
44
- * assert.isTrue(isNonPositiveInt(-5));
45
- *
46
- * assert.isFalse(isNonPositiveInt(1));
47
- * ```
35
+ * Returns `true` for a non-positive integer — a value with no fractional
36
+ * component, including values outside the safe integer range (unlike
37
+ * `SafeInt`).
48
38
  *
49
39
  * @param value - The value to check
50
40
  * @returns `true` if the value is a non-positive integer, `false` otherwise
@@ -52,200 +42,110 @@ const {
52
42
  export const isNonPositiveInt = is;
53
43
 
54
44
  /**
55
- * Casts a number to a NonPositiveInt branded type.
56
- *
57
- * This function validates that the input is a non-positive integer (<= 0) and
58
- * returns it with the NonPositiveInt brand. This ensures type safety for
59
- * operations that require non-positive integer values.
60
- *
61
- * @example
45
+ * Casts a `number` to the `NonPositiveInt` branded type.
62
46
  *
63
- * ```ts
64
- * const branded = asNonPositiveInt(-7);
65
- *
66
- * assert.isTrue(branded === -7);
67
- *
68
- * assert.isTrue(NonPositiveInt.is(branded));
69
- * ```
47
+ * Validates that the value is a non-positive integer and returns it with the
48
+ * `NonPositiveInt` brand. Throws a `TypeError` otherwise.
70
49
  *
71
50
  * @param value - The value to cast
72
- * @returns The value as a NonPositiveInt branded type
51
+ * @returns The value as a `NonPositiveInt`
73
52
  * @throws {TypeError} If the value is not a non-positive integer
74
53
  */
75
54
  export const asNonPositiveInt = castType;
76
55
 
77
56
  /**
78
- * Namespace providing type-safe operations for NonPositiveInt branded types.
79
- *
80
- * NonPositiveInt represents integers that are less than or equal to zero (<= 0).
81
- * All operations automatically clamp results to maintain the non-positive
82
- * constraint, ensuring that arithmetic operations never produce positive values.
57
+ * Namespace providing type-safe operations for the `NonPositiveInt` branded
58
+ * type.
83
59
  *
84
- * This type is essential for:
60
+ * The `NonPositiveInt` type represents a non-positive integer. Division (`div`)
61
+ * uses floor division.
85
62
  *
86
- * - Debts and negative balances
87
- * - Penalties and reductions
88
- * - Offsets and adjustments (downward)
89
- * - Negative counts or differences
90
- * - Depth or altitude below a reference point
63
+ * Unlike `SafeInt`, `NonPositiveInt` allows values outside the safe integer
64
+ * range (±2^53 − 1), so very large magnitudes may lose precision in
65
+ * JavaScript's `number` type.
91
66
  */
92
67
  export const NonPositiveInt = {
93
68
  /**
94
69
  * Type guard that checks if a value is a non-positive integer.
95
70
  *
96
- * @example
97
- *
98
- * ```ts
99
- * const value: number = -42;
100
- *
101
- * if (NonPositiveInt.is(value)) {
102
- * // value is now typed as NonPositiveInt
103
- * const debt = value;
104
- * }
105
- * ```
106
- *
107
71
  * @param value - The value to check
108
72
  * @returns `true` if the value is a non-positive integer, `false` otherwise
73
+ * @see {@link isNonPositiveInt} for usage examples
109
74
  */
110
75
  is,
111
76
 
112
77
  /**
113
- * The maximum value for a non-positive integer.
114
- *
115
- * @readonly
78
+ * The largest value representable as `NonPositiveInt` (the upper saturation
79
+ * target of `fromNumber`).
116
80
  */
117
81
  MAX_VALUE,
118
82
 
119
83
  /**
120
- * Returns the smaller of two non-positive integers.
121
- *
122
- * Since non-positive integers range from negative infinity to 0, the smaller
123
- * value is the one further from zero (more negative).
124
- *
125
- * @example
126
- *
127
- * ```ts
128
- * const result = NonPositiveInt.min(-5, -10);
129
- *
130
- * assert.strictEqual(result, -10);
131
- * ```
84
+ * Returns the smallest of the given non-positive integers.
132
85
  *
133
- * @param a - The first non-positive integer
134
- * @param b - The second non-positive integer
135
- * @returns The minimum value as a non-positive integer
86
+ * @param values - The non-positive integers to compare (at least one required)
87
+ * @returns The smallest value as a `NonPositiveInt`
136
88
  */
137
89
  min: min_,
138
90
 
139
91
  /**
140
- * Returns the larger of two non-positive integers.
141
- *
142
- * Since non-positive integers range from negative infinity to 0, the larger
143
- * value is the one closer to zero (less negative).
144
- *
145
- * @example
146
- *
147
- * ```ts
148
- * const result = NonPositiveInt.max(-5, -10);
92
+ * Returns the largest of the given non-positive integers.
149
93
  *
150
- * assert.strictEqual(result, -5);
151
- * ```
152
- *
153
- * @param a - The first non-positive integer
154
- * @param b - The second non-positive integer
155
- * @returns The maximum value as a non-positive integer
94
+ * @param values - The non-positive integers to compare (at least one required)
95
+ * @returns The largest value as a `NonPositiveInt`
156
96
  */
157
97
  max: max_,
158
98
 
159
99
  /**
160
- * Clamps a number to the non-positive integer range.
161
- *
162
- * Any positive value is clamped to 0 (the maximum non-positive integer).
163
- * Negative values are preserved as long as they are valid integers.
164
- *
165
- * @example
166
- *
167
- * ```ts
168
- * assert.strictEqual(NonPositiveInt.clamp(5), 0);
100
+ * Converts an arbitrary `number` into a `NonPositiveInt`, rounding to the
101
+ * nearest integer and saturating the result into the range `[MIN_VALUE,
102
+ * MAX_VALUE]`.
169
103
  *
170
- * assert.strictEqual(NonPositiveInt.clamp(-5), -5);
104
+ * Unlike `asNonPositiveInt`, this is total: out-of-range inputs are clamped
105
+ * to the nearest representable `NonPositiveInt` instead of throwing.
171
106
  *
172
- * assert.strictEqual(NonPositiveInt.clamp(0), 0);
173
- * ```
174
- *
175
- * @param value - The number to clamp
176
- * @returns The value clamped to the non-positive integer range
107
+ * @param value - The value to convert
108
+ * @returns The value as a `NonPositiveInt`
177
109
  */
178
- clamp,
110
+ fromNumber,
179
111
 
180
112
  /**
181
- * Generates a random non-positive integer value.
182
- *
183
- * @example
184
- *
185
- * ```ts
186
- * const randomValue = NonPositiveInt.random();
113
+ * Generates a random `NonPositiveInt` within the given range.
187
114
  *
188
- * assert.isTrue(NonPositiveInt.is(randomValue));
189
- * ```
115
+ * The range is inclusive on both ends.
190
116
  *
191
- * @returns A random non-positive integer
117
+ * @param min - The minimum value (inclusive)
118
+ * @param max - The maximum value (inclusive)
119
+ * @returns A random `NonPositiveInt` in `[min, max]`
192
120
  */
193
121
  random,
194
122
 
195
123
  /**
196
- * Raises a non-positive integer to the power of another non-positive integer.
197
- *
198
- * The result is clamped to the non-positive integer range.
199
- *
200
- * @example
201
- *
202
- * ```ts
203
- * const result = NonPositiveInt.pow(-2, -1);
204
- * ```
124
+ * Raises `a` to the power `b`, returning `a ** b` as a `NonPositiveInt`
125
+ * (floored to an integer).
205
126
  *
206
127
  * @param a - The base non-positive integer
207
128
  * @param b - The exponent non-positive integer
208
- * @returns `a ** b` clamped to the non-positive integer range
129
+ * @returns `a ** b` as a `NonPositiveInt`
209
130
  */
210
131
  pow,
211
132
 
212
133
  /**
213
- * Adds two non-positive integers.
214
- *
215
- * The result is clamped to the non-positive integer range. If the sum is
216
- * positive, it is clamped to 0.
217
- *
218
- * @example
219
- *
220
- * ```ts
221
- * assert.strictEqual(NonPositiveInt.add(-5, -3), -8);
222
- *
223
- * assert.strictEqual(NonPositiveInt.add(-5, 10), 0);
224
- * ```
134
+ * Adds two non-positive integers, returning `a + b` as a `NonPositiveInt`.
225
135
  *
226
136
  * @param a - The first non-positive integer
227
137
  * @param b - The second non-positive integer
228
- * @returns `a + b` clamped to the non-positive integer range
138
+ * @returns The sum of `a` and `b` as a `NonPositiveInt`
229
139
  */
230
140
  add,
231
141
 
232
142
  /**
233
- * Subtracts one non-positive integer from another.
234
- *
235
- * The result is clamped to the non-positive integer range. If the result is
236
- * positive, it is clamped to 0.
143
+ * Subtracts two non-positive integers, returning `a - b` as a
144
+ * `NonPositiveInt`.
237
145
  *
238
- * @example
239
- *
240
- * ```ts
241
- * assert.strictEqual(NonPositiveInt.sub(-10, -3), -7);
242
- *
243
- * assert.strictEqual(NonPositiveInt.sub(-10, 5), 0);
244
- * ```
245
- *
246
- * @param a - The minuend non-positive integer
247
- * @param b - The subtrahend non-positive integer
248
- * @returns `a - b` clamped to the non-positive integer range
146
+ * @param a - The first non-positive integer
147
+ * @param b - The second non-positive integer
148
+ * @returns The difference of `a` and `b` as a `NonPositiveInt`
249
149
  */
250
150
  sub,
251
151
  } as const;
@@ -131,23 +131,23 @@ describe('NonPositiveInt test', () => {
131
131
  });
132
132
  });
133
133
 
134
- describe('NonPositiveInt.clamp', () => {
134
+ describe('NonPositiveInt.fromNumber', () => {
135
135
  test('returns the same value if within range', () => {
136
- expect(NonPositiveInt.clamp(-5)).toBe(-5);
136
+ expect(NonPositiveInt.fromNumber(-5)).toBe(-5);
137
137
 
138
- expect(NonPositiveInt.clamp(0)).toBe(0);
138
+ expect(NonPositiveInt.fromNumber(0)).toBe(0);
139
139
 
140
- expect(NonPositiveInt.clamp(-1000)).toBe(-1000);
140
+ expect(NonPositiveInt.fromNumber(-1000)).toBe(-1000);
141
141
  });
142
142
 
143
143
  test('clamps positive values to MAX_VALUE (0)', () => {
144
- expect(NonPositiveInt.clamp(5)).toBe(0);
144
+ expect(NonPositiveInt.fromNumber(5)).toBe(0);
145
145
 
146
- expect(NonPositiveInt.clamp(1000)).toBe(0);
146
+ expect(NonPositiveInt.fromNumber(1000)).toBe(0);
147
147
  });
148
148
 
149
149
  test('clamps -Infinity to the lower bound', () => {
150
- expect(NonPositiveInt.clamp(Number.NEGATIVE_INFINITY)).toBe(
150
+ expect(NonPositiveInt.fromNumber(Number.NEGATIVE_INFINITY)).toBe(
151
151
  -Number.MAX_VALUE,
152
152
  );
153
153
  });
@@ -12,7 +12,7 @@ const {
12
12
  MIN_VALUE,
13
13
  add,
14
14
  castType,
15
- clamp,
15
+ fromNumber,
16
16
  is,
17
17
  max: max_,
18
18
  min: min_,
@@ -31,117 +31,125 @@ const {
31
31
  } as const);
32
32
 
33
33
  /**
34
- * Checks if a number is a NonPositiveSafeInt (non-positive safe integer in the
35
- * range [Number.MIN_SAFE_INTEGER, 0]).
34
+ * Type guard that checks if a value is a non-positive safe integer.
36
35
  *
37
- * @param value The value to check.
38
- * @returns `true` if the value is a NonPositiveSafeInt, `false` otherwise.
36
+ * Returns `true` for a non-positive safe integer — a value with no fractional
37
+ * component.
38
+ *
39
+ * @param value - The value to check
40
+ * @returns `true` if the value is a non-positive safe integer, `false` otherwise
39
41
  */
40
42
  export const isNonPositiveSafeInt = is;
41
43
 
42
44
  /**
43
- * Casts a number to a NonPositiveSafeInt type.
45
+ * Casts a `number` to the `NonPositiveSafeInt` branded type.
46
+ *
47
+ * Validates that the value is a non-positive safe integer and returns it with
48
+ * the `NonPositiveSafeInt` brand. Throws a `TypeError` otherwise.
44
49
  *
45
- * @param value The value to cast.
46
- * @returns The value as a NonPositiveSafeInt type.
47
- * @throws {TypeError} If the value is not a non-positive safe integer.
50
+ * @param value - The value to cast
51
+ * @returns The value as a `NonPositiveSafeInt`
52
+ * @throws {TypeError} If the value is not a non-positive safe integer
48
53
  */
49
54
  export const asNonPositiveSafeInt = castType;
50
55
 
51
56
  /**
52
- * Namespace providing type-safe arithmetic operations for non-positive
53
- * safe integers.
57
+ * Namespace providing type-safe operations for the `NonPositiveSafeInt` branded
58
+ * type.
54
59
  *
55
- * All operations automatically clamp results to the valid NonPositiveSafeInt
56
- * range [Number.MIN_SAFE_INTEGER, 0]. This ensures that all arithmetic
57
- * maintains the non-positive safe integer constraint, with positive results
58
- * clamped to 0 and underflow results clamped to MIN_VALUE.
60
+ * The `NonPositiveSafeInt` type represents a non-positive safe integer.
61
+ * Division (`div`) uses floor division.
59
62
  */
60
63
  export const NonPositiveSafeInt = {
61
64
  /**
62
- * Type guard to check if a value is a NonPositiveSafeInt.
65
+ * Type guard that checks if a value is a non-positive safe integer.
63
66
  *
64
- * @param value The value to check.
65
- * @returns `true` if the value is a non-positive safe integer, `false`
66
- * otherwise.
67
+ * @param value - The value to check
68
+ * @returns `true` if the value is a non-positive safe integer, `false` otherwise
69
+ * @see {@link isNonPositiveSafeInt} for usage examples
67
70
  */
68
71
  is,
69
72
 
70
73
  /**
71
- * The minimum value for a non-positive safe integer.
72
- *
73
- * @readonly
74
+ * The smallest value representable as `NonPositiveSafeInt` (the lower
75
+ * saturation target of `fromNumber`).
74
76
  */
75
77
  MIN_VALUE,
76
78
 
77
79
  /**
78
- * The maximum value for a non-positive safe integer.
79
- *
80
- * @readonly
80
+ * The largest value representable as `NonPositiveSafeInt` (the upper
81
+ * saturation target of `fromNumber`).
81
82
  */
82
83
  MAX_VALUE,
83
84
 
84
85
  /**
85
- * Returns the smaller of two NonPositiveSafeInt values.
86
+ * Returns the smallest of the given non-positive safe integers.
86
87
  *
87
- * @param a The first NonPositiveSafeInt.
88
- * @param b The second NonPositiveSafeInt.
89
- * @returns The minimum value as a NonPositiveSafeInt.
88
+ * @param values - The non-positive safe integers to compare (at least one required)
89
+ * @returns The smallest value as a `NonPositiveSafeInt`
90
90
  */
91
91
  min: min_,
92
92
 
93
93
  /**
94
- * Returns the larger of two NonPositiveSafeInt values.
94
+ * Returns the largest of the given non-positive safe integers.
95
95
  *
96
- * @param a The first NonPositiveSafeInt.
97
- * @param b The second NonPositiveSafeInt.
98
- * @returns The maximum value as a NonPositiveSafeInt.
96
+ * @param values - The non-positive safe integers to compare (at least one required)
97
+ * @returns The largest value as a `NonPositiveSafeInt`
99
98
  */
100
99
  max: max_,
101
100
 
102
101
  /**
103
- * Clamps a number to the NonPositiveSafeInt range.
102
+ * Converts an arbitrary `number` into a `NonPositiveSafeInt`, rounding to the
103
+ * nearest integer and saturating the result into the range `[MIN_VALUE,
104
+ * MAX_VALUE]`.
105
+ *
106
+ * Unlike `asNonPositiveSafeInt`, this is total: out-of-range inputs are
107
+ * clamped to the nearest representable `NonPositiveSafeInt` instead of
108
+ * throwing.
104
109
  *
105
- * @param value The number to clamp.
106
- * @returns The value clamped to [Number.MIN_SAFE_INTEGER, 0] as a
107
- * NonPositiveSafeInt.
110
+ * @param value - The value to convert
111
+ * @returns The value as a `NonPositiveSafeInt`
108
112
  */
109
- clamp,
113
+ fromNumber,
110
114
 
111
115
  /**
112
- * Generates a random NonPositiveSafeInt value within the valid range.
116
+ * Generates a random `NonPositiveSafeInt` within the given range.
117
+ *
118
+ * The range is inclusive on both ends.
113
119
  *
114
- * @returns A random NonPositiveSafeInt between Number.MIN_SAFE_INTEGER and 0.
120
+ * @param min - The minimum value (inclusive)
121
+ * @param max - The maximum value (inclusive)
122
+ * @returns A random `NonPositiveSafeInt` in `[min, max]`
115
123
  */
116
124
  random,
117
125
 
118
126
  /**
119
- * Raises a NonPositiveSafeInt to the power of another NonPositiveSafeInt.
127
+ * Raises `a` to the power `b`, returning `a ** b` as a `NonPositiveSafeInt`
128
+ * (floored to an integer).
120
129
  *
121
- * @param a The base NonPositiveSafeInt.
122
- * @param b The exponent NonPositiveSafeInt.
123
- * @returns `a ** b` clamped to [Number.MIN_SAFE_INTEGER, 0] as a
124
- * NonPositiveSafeInt.
130
+ * @param a - The base non-positive safe integer
131
+ * @param b - The exponent non-positive safe integer
132
+ * @returns `a ** b` as a `NonPositiveSafeInt`
125
133
  */
126
134
  pow,
127
135
 
128
136
  /**
129
- * Adds two NonPositiveSafeInt values.
137
+ * Adds two non-positive safe integers, returning `a + b` as a
138
+ * `NonPositiveSafeInt`.
130
139
  *
131
- * @param a The first NonPositiveSafeInt.
132
- * @param b The second NonPositiveSafeInt.
133
- * @returns `a + b` clamped to [Number.MIN_SAFE_INTEGER, 0] as a
134
- * NonPositiveSafeInt.
140
+ * @param a - The first non-positive safe integer
141
+ * @param b - The second non-positive safe integer
142
+ * @returns The sum of `a` and `b` as a `NonPositiveSafeInt`
135
143
  */
136
144
  add,
137
145
 
138
146
  /**
139
- * Subtracts one NonPositiveSafeInt from another.
147
+ * Subtracts two non-positive safe integers, returning `a - b` as a
148
+ * `NonPositiveSafeInt`.
140
149
  *
141
- * @param a The minuend NonPositiveSafeInt.
142
- * @param b The subtrahend NonPositiveSafeInt.
143
- * @returns `a - b` clamped to [Number.MIN_SAFE_INTEGER, 0] as a
144
- * NonPositiveSafeInt (maximum 0).
150
+ * @param a - The first non-positive safe integer
151
+ * @param b - The second non-positive safe integer
152
+ * @returns The difference of `a` and `b` as a `NonPositiveSafeInt`
145
153
  */
146
154
  sub,
147
155
  } as const;
@@ -163,23 +163,23 @@ describe('NonPositiveSafeInt test', () => {
163
163
  });
164
164
  });
165
165
 
166
- describe('NonPositiveSafeInt.clamp', () => {
166
+ describe('NonPositiveSafeInt.fromNumber', () => {
167
167
  test('returns the same value if within range', () => {
168
- expect(NonPositiveSafeInt.clamp(-5)).toBe(-5);
168
+ expect(NonPositiveSafeInt.fromNumber(-5)).toBe(-5);
169
169
 
170
- expect(NonPositiveSafeInt.clamp(0)).toBe(0);
170
+ expect(NonPositiveSafeInt.fromNumber(0)).toBe(0);
171
171
 
172
- expect(NonPositiveSafeInt.clamp(-1000)).toBe(-1000);
172
+ expect(NonPositiveSafeInt.fromNumber(-1000)).toBe(-1000);
173
173
  });
174
174
 
175
175
  test('clamps positive values to MAX_VALUE (0)', () => {
176
- expect(NonPositiveSafeInt.clamp(5)).toBe(0);
176
+ expect(NonPositiveSafeInt.fromNumber(5)).toBe(0);
177
177
 
178
- expect(NonPositiveSafeInt.clamp(1000)).toBe(0);
178
+ expect(NonPositiveSafeInt.fromNumber(1000)).toBe(0);
179
179
  });
180
180
 
181
181
  test('clamps out-of-range negative values to MIN_VALUE', () => {
182
- expect(NonPositiveSafeInt.clamp(Number.MIN_SAFE_INTEGER - 1)).toBe(
182
+ expect(NonPositiveSafeInt.fromNumber(Number.MIN_SAFE_INTEGER - 1)).toBe(
183
183
  Number.MIN_SAFE_INTEGER,
184
184
  );
185
185
  });