ts-data-forge 11.0.1 → 12.1.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 (178) hide show
  1. package/README.md +2 -2
  2. package/dist/array/impl/array-utils-length-bounded-array-cast.d.mts +65 -5
  3. package/dist/array/impl/array-utils-length-bounded-array-cast.d.mts.map +1 -1
  4. package/dist/array/impl/array-utils-length-bounded-array-cast.mjs +69 -27
  5. package/dist/array/impl/array-utils-length-bounded-array-cast.mjs.map +1 -1
  6. package/dist/array/impl/index.mjs +1 -1
  7. package/dist/number/branded-types/int16.d.mts +12 -7
  8. package/dist/number/branded-types/int16.d.mts.map +1 -1
  9. package/dist/number/branded-types/int16.mjs +13 -8
  10. package/dist/number/branded-types/int16.mjs.map +1 -1
  11. package/dist/number/branded-types/int32.d.mts +12 -7
  12. package/dist/number/branded-types/int32.d.mts.map +1 -1
  13. package/dist/number/branded-types/int32.mjs +13 -8
  14. package/dist/number/branded-types/int32.mjs.map +1 -1
  15. package/dist/number/branded-types/negative-finite-number.d.mts +13 -6
  16. package/dist/number/branded-types/negative-finite-number.d.mts.map +1 -1
  17. package/dist/number/branded-types/negative-finite-number.mjs +15 -8
  18. package/dist/number/branded-types/negative-finite-number.mjs.map +1 -1
  19. package/dist/number/branded-types/negative-int.d.mts +11 -6
  20. package/dist/number/branded-types/negative-int.d.mts.map +1 -1
  21. package/dist/number/branded-types/negative-int.mjs +13 -8
  22. package/dist/number/branded-types/negative-int.mjs.map +1 -1
  23. package/dist/number/branded-types/negative-safe-int.d.mts +13 -7
  24. package/dist/number/branded-types/negative-safe-int.d.mts.map +1 -1
  25. package/dist/number/branded-types/negative-safe-int.mjs +15 -9
  26. package/dist/number/branded-types/negative-safe-int.mjs.map +1 -1
  27. package/dist/number/branded-types/non-negative-finite-number.d.mts +11 -6
  28. package/dist/number/branded-types/non-negative-finite-number.d.mts.map +1 -1
  29. package/dist/number/branded-types/non-negative-finite-number.mjs +12 -7
  30. package/dist/number/branded-types/non-negative-finite-number.mjs.map +1 -1
  31. package/dist/number/branded-types/non-negative-int16.d.mts +13 -7
  32. package/dist/number/branded-types/non-negative-int16.d.mts.map +1 -1
  33. package/dist/number/branded-types/non-negative-int16.mjs +14 -8
  34. package/dist/number/branded-types/non-negative-int16.mjs.map +1 -1
  35. package/dist/number/branded-types/non-negative-int32.d.mts +13 -7
  36. package/dist/number/branded-types/non-negative-int32.d.mts.map +1 -1
  37. package/dist/number/branded-types/non-negative-int32.mjs +14 -8
  38. package/dist/number/branded-types/non-negative-int32.mjs.map +1 -1
  39. package/dist/number/branded-types/non-positive-finite-number.d.mts +11 -6
  40. package/dist/number/branded-types/non-positive-finite-number.d.mts.map +1 -1
  41. package/dist/number/branded-types/non-positive-finite-number.mjs +12 -7
  42. package/dist/number/branded-types/non-positive-finite-number.mjs.map +1 -1
  43. package/dist/number/branded-types/non-positive-int.d.mts +11 -6
  44. package/dist/number/branded-types/non-positive-int.d.mts.map +1 -1
  45. package/dist/number/branded-types/non-positive-int.mjs +12 -7
  46. package/dist/number/branded-types/non-positive-int.mjs.map +1 -1
  47. package/dist/number/branded-types/non-positive-safe-int.d.mts +14 -7
  48. package/dist/number/branded-types/non-positive-safe-int.d.mts.map +1 -1
  49. package/dist/number/branded-types/non-positive-safe-int.mjs +15 -8
  50. package/dist/number/branded-types/non-positive-safe-int.mjs.map +1 -1
  51. package/dist/number/branded-types/non-zero-int16.d.mts +13 -7
  52. package/dist/number/branded-types/non-zero-int16.d.mts.map +1 -1
  53. package/dist/number/branded-types/non-zero-int16.mjs +14 -8
  54. package/dist/number/branded-types/non-zero-int16.mjs.map +1 -1
  55. package/dist/number/branded-types/non-zero-int32.d.mts +13 -7
  56. package/dist/number/branded-types/non-zero-int32.d.mts.map +1 -1
  57. package/dist/number/branded-types/non-zero-int32.mjs +14 -8
  58. package/dist/number/branded-types/non-zero-int32.mjs.map +1 -1
  59. package/dist/number/branded-types/non-zero-safe-int.d.mts +13 -7
  60. package/dist/number/branded-types/non-zero-safe-int.d.mts.map +1 -1
  61. package/dist/number/branded-types/non-zero-safe-int.mjs +14 -8
  62. package/dist/number/branded-types/non-zero-safe-int.mjs.map +1 -1
  63. package/dist/number/branded-types/non-zero-uint16.d.mts +13 -7
  64. package/dist/number/branded-types/non-zero-uint16.d.mts.map +1 -1
  65. package/dist/number/branded-types/non-zero-uint16.mjs +14 -8
  66. package/dist/number/branded-types/non-zero-uint16.mjs.map +1 -1
  67. package/dist/number/branded-types/non-zero-uint32.d.mts +13 -7
  68. package/dist/number/branded-types/non-zero-uint32.d.mts.map +1 -1
  69. package/dist/number/branded-types/non-zero-uint32.mjs +14 -8
  70. package/dist/number/branded-types/non-zero-uint32.mjs.map +1 -1
  71. package/dist/number/branded-types/positive-finite-number.d.mts +13 -6
  72. package/dist/number/branded-types/positive-finite-number.d.mts.map +1 -1
  73. package/dist/number/branded-types/positive-finite-number.mjs +14 -7
  74. package/dist/number/branded-types/positive-finite-number.mjs.map +1 -1
  75. package/dist/number/branded-types/positive-int.d.mts +13 -8
  76. package/dist/number/branded-types/positive-int.d.mts.map +1 -1
  77. package/dist/number/branded-types/positive-int.mjs +14 -9
  78. package/dist/number/branded-types/positive-int.mjs.map +1 -1
  79. package/dist/number/branded-types/positive-int16.d.mts +13 -7
  80. package/dist/number/branded-types/positive-int16.d.mts.map +1 -1
  81. package/dist/number/branded-types/positive-int16.mjs +14 -8
  82. package/dist/number/branded-types/positive-int16.mjs.map +1 -1
  83. package/dist/number/branded-types/positive-int32.d.mts +13 -7
  84. package/dist/number/branded-types/positive-int32.d.mts.map +1 -1
  85. package/dist/number/branded-types/positive-int32.mjs +14 -8
  86. package/dist/number/branded-types/positive-int32.mjs.map +1 -1
  87. package/dist/number/branded-types/positive-safe-int.d.mts +16 -10
  88. package/dist/number/branded-types/positive-safe-int.d.mts.map +1 -1
  89. package/dist/number/branded-types/positive-safe-int.mjs +17 -11
  90. package/dist/number/branded-types/positive-safe-int.mjs.map +1 -1
  91. package/dist/number/branded-types/positive-uint16.d.mts +13 -7
  92. package/dist/number/branded-types/positive-uint16.d.mts.map +1 -1
  93. package/dist/number/branded-types/positive-uint16.mjs +14 -8
  94. package/dist/number/branded-types/positive-uint16.mjs.map +1 -1
  95. package/dist/number/branded-types/positive-uint32.d.mts +13 -7
  96. package/dist/number/branded-types/positive-uint32.d.mts.map +1 -1
  97. package/dist/number/branded-types/positive-uint32.mjs +14 -8
  98. package/dist/number/branded-types/positive-uint32.mjs.map +1 -1
  99. package/dist/number/branded-types/safe-int.d.mts +15 -10
  100. package/dist/number/branded-types/safe-int.d.mts.map +1 -1
  101. package/dist/number/branded-types/safe-int.mjs +16 -11
  102. package/dist/number/branded-types/safe-int.mjs.map +1 -1
  103. package/dist/number/branded-types/safe-uint.d.mts +12 -7
  104. package/dist/number/branded-types/safe-uint.d.mts.map +1 -1
  105. package/dist/number/branded-types/safe-uint.mjs +13 -8
  106. package/dist/number/branded-types/safe-uint.mjs.map +1 -1
  107. package/dist/number/branded-types/uint.d.mts +14 -10
  108. package/dist/number/branded-types/uint.d.mts.map +1 -1
  109. package/dist/number/branded-types/uint.mjs +15 -11
  110. package/dist/number/branded-types/uint.mjs.map +1 -1
  111. package/dist/number/branded-types/uint16.d.mts +12 -7
  112. package/dist/number/branded-types/uint16.d.mts.map +1 -1
  113. package/dist/number/branded-types/uint16.mjs +13 -8
  114. package/dist/number/branded-types/uint16.mjs.map +1 -1
  115. package/dist/number/branded-types/uint32.d.mts +12 -7
  116. package/dist/number/branded-types/uint32.d.mts.map +1 -1
  117. package/dist/number/branded-types/uint32.mjs +13 -8
  118. package/dist/number/branded-types/uint32.mjs.map +1 -1
  119. package/dist/number/enum/int8.d.mts +12 -7
  120. package/dist/number/enum/int8.d.mts.map +1 -1
  121. package/dist/number/enum/int8.mjs +19 -14
  122. package/dist/number/enum/int8.mjs.map +1 -1
  123. package/dist/number/enum/uint8.d.mts +12 -7
  124. package/dist/number/enum/uint8.d.mts.map +1 -1
  125. package/dist/number/enum/uint8.mjs +19 -14
  126. package/dist/number/enum/uint8.mjs.map +1 -1
  127. package/dist/number/refined-number-utils.d.mts +9 -9
  128. package/dist/number/refined-number-utils.d.mts.map +1 -1
  129. package/dist/number/refined-number-utils.mjs +7 -7
  130. package/dist/number/refined-number-utils.mjs.map +1 -1
  131. package/dist/string/str.d.mts +70 -5
  132. package/dist/string/str.d.mts.map +1 -1
  133. package/dist/string/str.mjs +72 -26
  134. package/dist/string/str.mjs.map +1 -1
  135. package/package.json +1 -1
  136. package/src/array/impl/array-utils-length-bounded-array-cast.mts +204 -39
  137. package/src/array/impl/array-utils-length-bounded-array-cast.test.mts +126 -0
  138. package/src/number/branded-types/int16.mts +13 -8
  139. package/src/number/branded-types/int32.mts +13 -8
  140. package/src/number/branded-types/negative-finite-number.mts +15 -8
  141. package/src/number/branded-types/negative-finite-number.test.mts +4 -4
  142. package/src/number/branded-types/negative-int.mts +13 -8
  143. package/src/number/branded-types/negative-int.test.mts +5 -5
  144. package/src/number/branded-types/negative-safe-int.mts +15 -9
  145. package/src/number/branded-types/negative-safe-int.test.mts +4 -4
  146. package/src/number/branded-types/non-negative-finite-number.mts +12 -7
  147. package/src/number/branded-types/non-negative-int16.mts +14 -8
  148. package/src/number/branded-types/non-negative-int32.mts +14 -8
  149. package/src/number/branded-types/non-positive-finite-number.mts +12 -7
  150. package/src/number/branded-types/non-positive-finite-number.test.mts +7 -7
  151. package/src/number/branded-types/non-positive-int.mts +12 -7
  152. package/src/number/branded-types/non-positive-int.test.mts +7 -7
  153. package/src/number/branded-types/non-positive-safe-int.mts +15 -8
  154. package/src/number/branded-types/non-positive-safe-int.test.mts +7 -7
  155. package/src/number/branded-types/non-zero-int16.mts +14 -8
  156. package/src/number/branded-types/non-zero-int32.mts +14 -8
  157. package/src/number/branded-types/non-zero-safe-int.mts +14 -8
  158. package/src/number/branded-types/non-zero-uint16.mts +14 -8
  159. package/src/number/branded-types/non-zero-uint32.mts +14 -8
  160. package/src/number/branded-types/positive-finite-number.mts +14 -7
  161. package/src/number/branded-types/positive-int.mts +14 -9
  162. package/src/number/branded-types/positive-int16.mts +14 -8
  163. package/src/number/branded-types/positive-int32.mts +14 -8
  164. package/src/number/branded-types/positive-safe-int.mts +17 -11
  165. package/src/number/branded-types/positive-uint16.mts +14 -8
  166. package/src/number/branded-types/positive-uint32.mts +14 -8
  167. package/src/number/branded-types/safe-int.mts +16 -11
  168. package/src/number/branded-types/safe-uint.mts +13 -8
  169. package/src/number/branded-types/uint.mts +15 -11
  170. package/src/number/branded-types/uint16.mts +13 -8
  171. package/src/number/branded-types/uint32.mts +13 -8
  172. package/src/number/enum/int8.mts +20 -14
  173. package/src/number/enum/int8.test.mts +7 -4
  174. package/src/number/enum/uint8.mts +20 -14
  175. package/src/number/enum/uint8.test.mts +7 -4
  176. package/src/number/refined-number-utils.mts +22 -19
  177. package/src/string/str.mts +201 -39
  178. package/src/string/str.test.mts +76 -0
@@ -12,8 +12,8 @@ const {
12
12
  MIN_VALUE,
13
13
  add,
14
14
  castType,
15
- clamp,
16
15
  div,
16
+ fromNumber,
17
17
  is,
18
18
  max: max_,
19
19
  min: min_,
@@ -107,7 +107,8 @@ export const Uint = {
107
107
  is,
108
108
 
109
109
  /**
110
- * The smallest value representable as `Uint`.
110
+ * The smallest value representable as `Uint` (the lower saturation target of
111
+ * `fromNumber`).
111
112
  */
112
113
  MIN_VALUE,
113
114
 
@@ -144,25 +145,28 @@ export const Uint = {
144
145
  max: max_,
145
146
 
146
147
  /**
147
- * Clamps a `number` into the `Uint` range, rounding to the nearest integer
148
- * and constraining the result to `[MIN_VALUE, MAX_VALUE]`.
148
+ * Converts an arbitrary `number` into an `Uint`, rounding to the nearest
149
+ * integer and saturating the result into the range `[MIN_VALUE, MAX_VALUE]`.
150
+ *
151
+ * Unlike `asUint`, this is total: out-of-range inputs are clamped to the
152
+ * nearest representable `Uint` instead of throwing.
149
153
  *
150
154
  * @example
151
155
  *
152
156
  * ```ts
153
- * const clampedNegative = Uint.clamp(-5);
157
+ * const fromNegative = Uint.fromNumber(-5);
154
158
  *
155
- * const clampedPositive = Uint.clamp(42);
159
+ * const fromPositive = Uint.fromNumber(42);
156
160
  *
157
- * assert.isTrue(clampedNegative === 0);
161
+ * assert.isTrue(fromNegative === 0);
158
162
  *
159
- * assert.isTrue(clampedPositive === 42);
163
+ * assert.isTrue(fromPositive === 42);
160
164
  * ```
161
165
  *
162
- * @param value - The value to clamp
163
- * @returns The clamped value as an `Uint`
166
+ * @param value - The value to convert
167
+ * @returns The value as an `Uint`
164
168
  */
165
- clamp,
169
+ fromNumber,
166
170
 
167
171
  /**
168
172
  * Generates a random `Uint` within the given range.
@@ -13,8 +13,8 @@ const {
13
13
  MIN_VALUE,
14
14
  add,
15
15
  castType,
16
- clamp,
17
16
  div,
17
+ fromNumber,
18
18
  is,
19
19
  max: max_,
20
20
  min: min_,
@@ -73,12 +73,14 @@ export const Uint16 = {
73
73
  is,
74
74
 
75
75
  /**
76
- * The smallest value representable as `Uint16`.
76
+ * The smallest value representable as `Uint16` (the lower saturation target
77
+ * of `fromNumber`).
77
78
  */
78
79
  MIN_VALUE,
79
80
 
80
81
  /**
81
- * The largest value representable as `Uint16`.
82
+ * The largest value representable as `Uint16` (the upper saturation target of
83
+ * `fromNumber`).
82
84
  */
83
85
  MAX_VALUE,
84
86
 
@@ -99,13 +101,16 @@ export const Uint16 = {
99
101
  max: max_,
100
102
 
101
103
  /**
102
- * Clamps a `number` into the `Uint16` range, rounding to the nearest integer
103
- * and constraining the result to `[MIN_VALUE, MAX_VALUE]`.
104
+ * Converts an arbitrary `number` into an `Uint16`, rounding to the nearest
105
+ * integer and saturating the result into the range `[MIN_VALUE, MAX_VALUE]`.
104
106
  *
105
- * @param value - The value to clamp
106
- * @returns The clamped value as an `Uint16`
107
+ * Unlike `asUint16`, this is total: out-of-range inputs are clamped to the
108
+ * nearest representable `Uint16` instead of throwing.
109
+ *
110
+ * @param value - The value to convert
111
+ * @returns The value as an `Uint16`
107
112
  */
108
- clamp,
113
+ fromNumber,
109
114
 
110
115
  /**
111
116
  * Generates a random `Uint16` within the given range.
@@ -13,8 +13,8 @@ const {
13
13
  MIN_VALUE,
14
14
  add,
15
15
  castType,
16
- clamp,
17
16
  div,
17
+ fromNumber,
18
18
  is,
19
19
  max: max_,
20
20
  min: min_,
@@ -73,12 +73,14 @@ export const Uint32 = {
73
73
  is,
74
74
 
75
75
  /**
76
- * The smallest value representable as `Uint32`.
76
+ * The smallest value representable as `Uint32` (the lower saturation target
77
+ * of `fromNumber`).
77
78
  */
78
79
  MIN_VALUE,
79
80
 
80
81
  /**
81
- * The largest value representable as `Uint32`.
82
+ * The largest value representable as `Uint32` (the upper saturation target of
83
+ * `fromNumber`).
82
84
  */
83
85
  MAX_VALUE,
84
86
 
@@ -99,13 +101,16 @@ export const Uint32 = {
99
101
  max: max_,
100
102
 
101
103
  /**
102
- * Clamps a `number` into the `Uint32` range, rounding to the nearest integer
103
- * and constraining the result to `[MIN_VALUE, MAX_VALUE]`.
104
+ * Converts an arbitrary `number` into an `Uint32`, rounding to the nearest
105
+ * integer and saturating the result into the range `[MIN_VALUE, MAX_VALUE]`.
104
106
  *
105
- * @param value - The value to clamp
106
- * @returns The clamped value as an `Uint32`
107
+ * Unlike `asUint32`, this is total: out-of-range inputs are clamped to the
108
+ * nearest representable `Uint32` instead of throwing.
109
+ *
110
+ * @param value - The value to convert
111
+ * @returns The value as an `Uint32`
107
112
  */
108
- clamp,
113
+ fromNumber,
109
114
 
110
115
  /**
111
116
  * Generates a random `Uint32` within the given range.
@@ -14,7 +14,7 @@ const {
14
14
  MAX_VALUE,
15
15
  MIN_VALUE,
16
16
  castType: castTypeImpl,
17
- clamp: clampImpl,
17
+ fromNumber: fromNumberImpl,
18
18
  is: isImpl,
19
19
  random: randomImpl,
20
20
  } = TsDataForgeInternals.RefinedNumberUtils.operatorsForInteger<
@@ -34,7 +34,7 @@ const castType = (x: number): Int8 =>
34
34
  // eslint-disable-next-line total-functions/no-unsafe-type-assertion
35
35
  castTypeImpl(x) as Int8;
36
36
 
37
- const clamp = (a: number): Int8 => castType(clampImpl(a));
37
+ const fromNumber = (a: number): Int8 => castType(fromNumberImpl(a));
38
38
 
39
39
  const abs = <N extends Int8>(x: N): AbsoluteValue<N> =>
40
40
  // eslint-disable-next-line total-functions/no-unsafe-type-assertion
@@ -46,15 +46,16 @@ const min_ = (...values: readonly Int8[]): Int8 =>
46
46
  const max_ = (...values: readonly Int8[]): Int8 =>
47
47
  castType(Math.max(...values));
48
48
 
49
- const pow = (x: Int8, y: Int8): Int8 => clamp(x ** y);
49
+ const pow = (x: Int8, y: Int8): Int8 => fromNumber(x ** y);
50
50
 
51
- const add = (x: Int8, y: Int8): Int8 => clamp(x + y);
51
+ const add = (x: Int8, y: Int8): Int8 => fromNumber(x + y);
52
52
 
53
- const sub = (x: Int8, y: Int8): Int8 => clamp(x - y);
53
+ const sub = (x: Int8, y: Int8): Int8 => fromNumber(x - y);
54
54
 
55
- const mul = (x: Int8, y: Int8): Int8 => clamp(x * y);
55
+ const mul = (x: Int8, y: Int8): Int8 => fromNumber(x * y);
56
56
 
57
- const div = (x: Int8, y: Exclude<Int8, 0>): Int8 => clamp(Math.floor(x / y));
57
+ const div = (x: Int8, y: Exclude<Int8, 0>): Int8 =>
58
+ fromNumber(Math.floor(x / y));
58
59
 
59
60
  const random = (min: Int8, max: Int8): Int8 =>
60
61
  castType(randomImpl(castTypeImpl(min), castTypeImpl(max)));
@@ -99,12 +100,14 @@ export const Int8 = {
99
100
  is,
100
101
 
101
102
  /**
102
- * The smallest value representable as `Int8`.
103
+ * The smallest value representable as `Int8` (the lower saturation target of
104
+ * `fromNumber`).
103
105
  */
104
106
  MIN_VALUE,
105
107
 
106
108
  /**
107
- * The largest value representable as `Int8`.
109
+ * The largest value representable as `Int8` (the upper saturation target of
110
+ * `fromNumber`).
108
111
  */
109
112
  MAX_VALUE,
110
113
 
@@ -125,13 +128,16 @@ export const Int8 = {
125
128
  max: max_,
126
129
 
127
130
  /**
128
- * Clamps a `number` into the `Int8` range, rounding to the nearest integer
129
- * and constraining the result to `[MIN_VALUE, MAX_VALUE]`.
131
+ * Converts an arbitrary `number` into an `Int8`, rounding to the nearest
132
+ * integer and saturating the result into the range `[MIN_VALUE, MAX_VALUE]`.
130
133
  *
131
- * @param value - The value to clamp
132
- * @returns The clamped value as an `Int8`
134
+ * Unlike `asInt8`, this is total: out-of-range inputs are clamped to the
135
+ * nearest representable `Int8` instead of throwing.
136
+ *
137
+ * @param value - The value to convert
138
+ * @returns The value as an `Int8`
133
139
  */
134
- clamp,
140
+ fromNumber,
135
141
 
136
142
  /**
137
143
  * Returns the absolute value of an integer in [-128, 127].
@@ -61,7 +61,7 @@ describe('Int8 test', () => {
61
61
  });
62
62
  });
63
63
 
64
- describe('Int8.clamp', () => {
64
+ describe('Int8.fromNumber', () => {
65
65
  test.each([
66
66
  { value: -200, expected: -128 },
67
67
  { value: -128, expected: -128 },
@@ -69,9 +69,12 @@ describe('Int8 test', () => {
69
69
  { value: 127, expected: 127 },
70
70
  { value: 200, expected: 127 },
71
71
  { value: 1.5, expected: 2 },
72
- ])('Int8.clamp($value) should return $expected', ({ expected, value }) => {
73
- expect(Int8.clamp(value)).toBe(expected);
74
- });
72
+ ])(
73
+ 'Int8.fromNumber($value) should return $expected',
74
+ ({ expected, value }) => {
75
+ expect(Int8.fromNumber(value)).toBe(expected);
76
+ },
77
+ );
75
78
  });
76
79
 
77
80
  describe('Int8.min', () => {
@@ -10,7 +10,7 @@ const {
10
10
  MAX_VALUE,
11
11
  MIN_VALUE,
12
12
  castType: castTypeImpl,
13
- clamp: clampImpl,
13
+ fromNumber: fromNumberImpl,
14
14
  is: isImpl,
15
15
  random: randomImpl,
16
16
  } = TsDataForgeInternals.RefinedNumberUtils.operatorsForInteger<Uint16, 0, 255>(
@@ -28,7 +28,7 @@ const castType = (x: number): Uint8 =>
28
28
  // eslint-disable-next-line total-functions/no-unsafe-type-assertion
29
29
  castTypeImpl(x) as Uint8;
30
30
 
31
- const clamp = (a: number): Uint8 => castType(clampImpl(a));
31
+ const fromNumber = (a: number): Uint8 => castType(fromNumberImpl(a));
32
32
 
33
33
  const min_ = (...values: readonly Uint8[]): Uint8 =>
34
34
  castType(Math.min(...values));
@@ -36,15 +36,16 @@ const min_ = (...values: readonly Uint8[]): Uint8 =>
36
36
  const max_ = (...values: readonly Uint8[]): Uint8 =>
37
37
  castType(Math.max(...values));
38
38
 
39
- const pow = (x: Uint8, y: Uint8): Uint8 => clamp(x ** y);
39
+ const pow = (x: Uint8, y: Uint8): Uint8 => fromNumber(x ** y);
40
40
 
41
- const add = (x: Uint8, y: Uint8): Uint8 => clamp(x + y);
41
+ const add = (x: Uint8, y: Uint8): Uint8 => fromNumber(x + y);
42
42
 
43
- const sub = (x: Uint8, y: Uint8): Uint8 => clamp(x - y);
43
+ const sub = (x: Uint8, y: Uint8): Uint8 => fromNumber(x - y);
44
44
 
45
- const mul = (x: Uint8, y: Uint8): Uint8 => clamp(x * y);
45
+ const mul = (x: Uint8, y: Uint8): Uint8 => fromNumber(x * y);
46
46
 
47
- const div = (x: Uint8, y: Exclude<Uint8, 0>): Uint8 => clamp(Math.floor(x / y));
47
+ const div = (x: Uint8, y: Exclude<Uint8, 0>): Uint8 =>
48
+ fromNumber(Math.floor(x / y));
48
49
 
49
50
  const random = (min: Uint8, max: Uint8): Uint8 =>
50
51
  castType(randomImpl(castTypeImpl(min), castTypeImpl(max)));
@@ -89,12 +90,14 @@ export const Uint8 = {
89
90
  is,
90
91
 
91
92
  /**
92
- * The smallest value representable as `Uint8`.
93
+ * The smallest value representable as `Uint8` (the lower saturation target of
94
+ * `fromNumber`).
93
95
  */
94
96
  MIN_VALUE,
95
97
 
96
98
  /**
97
- * The largest value representable as `Uint8`.
99
+ * The largest value representable as `Uint8` (the upper saturation target of
100
+ * `fromNumber`).
98
101
  */
99
102
  MAX_VALUE,
100
103
 
@@ -115,13 +118,16 @@ export const Uint8 = {
115
118
  min: min_,
116
119
 
117
120
  /**
118
- * Clamps a `number` into the `Uint8` range, rounding to the nearest integer
119
- * and constraining the result to `[MIN_VALUE, MAX_VALUE]`.
121
+ * Converts an arbitrary `number` into an `Uint8`, rounding to the nearest
122
+ * integer and saturating the result into the range `[MIN_VALUE, MAX_VALUE]`.
120
123
  *
121
- * @param value - The value to clamp
122
- * @returns The clamped value as an `Uint8`
124
+ * Unlike `asUint8`, this is total: out-of-range inputs are clamped to the
125
+ * nearest representable `Uint8` instead of throwing.
126
+ *
127
+ * @param value - The value to convert
128
+ * @returns The value as an `Uint8`
123
129
  */
124
- clamp,
130
+ fromNumber,
125
131
 
126
132
  /**
127
133
  * Generates a random `Uint8` within the given range.
@@ -61,7 +61,7 @@ describe('Uint8 test', () => {
61
61
  });
62
62
  });
63
63
 
64
- describe('Uint8.clamp', () => {
64
+ describe('Uint8.fromNumber', () => {
65
65
  test.each([
66
66
  { value: -100, expected: 0 },
67
67
  { value: 0, expected: 0 },
@@ -69,9 +69,12 @@ describe('Uint8 test', () => {
69
69
  { value: 255, expected: 255 },
70
70
  { value: 300, expected: 255 },
71
71
  { value: 1.5, expected: 2 },
72
- ])('Uint8.clamp($value) should return $expected', ({ expected, value }) => {
73
- expect(Uint8.clamp(value)).toBe(expected);
74
- });
72
+ ])(
73
+ 'Uint8.fromNumber($value) should return $expected',
74
+ ({ expected, value }) => {
75
+ expect(Uint8.fromNumber(value)).toBe(expected);
76
+ },
77
+ );
75
78
  });
76
79
 
77
80
  describe('Uint8.min', () => {
@@ -144,7 +144,7 @@ export namespace TsDataForgeInternals {
144
144
  ('non-negative' extends classes
145
145
  ? Readonly<{
146
146
  MIN_VALUE: number;
147
- clamp: (a: number) => N;
147
+ fromNumber: (a: number) => N;
148
148
  }>
149
149
  : unknown) &
150
150
  ('non-negative' extends classes
@@ -157,14 +157,14 @@ export namespace TsDataForgeInternals {
157
157
  ('positive' extends classes
158
158
  ? Readonly<{
159
159
  MIN_VALUE: number;
160
- clamp: (a: number) => N;
160
+ fromNumber: (a: number) => N;
161
161
  }>
162
162
  : unknown) &
163
163
  ('range' extends classes
164
164
  ? Readonly<{
165
165
  MIN_VALUE: number;
166
166
  MAX_VALUE: number;
167
- clamp: (a: number) => N;
167
+ fromNumber: (a: number) => N;
168
168
  }>
169
169
  : unknown) &
170
170
  Pick<
@@ -200,17 +200,17 @@ export namespace TsDataForgeInternals {
200
200
 
201
201
  expectType<
202
202
  keyof NumberClass<UnknownNumberBrand, 'non-negative'>,
203
- BaseKeys | FloatMethods | 'clamp' | 'MIN_VALUE'
203
+ BaseKeys | FloatMethods | 'fromNumber' | 'MIN_VALUE'
204
204
  >('=');
205
205
 
206
206
  expectType<
207
207
  keyof NumberClass<UnknownNumberBrand, 'positive'>,
208
- BaseKeys | FloatMethods | 'clamp' | 'MIN_VALUE'
208
+ BaseKeys | FloatMethods | 'fromNumber' | 'MIN_VALUE'
209
209
  >('=');
210
210
 
211
211
  expectType<
212
212
  keyof NumberClass<UnknownNumberBrand, 'int' | 'range'>,
213
- BaseKeys | 'abs' | 'clamp' | 'MAX_VALUE' | 'MIN_VALUE'
213
+ BaseKeys | 'abs' | 'fromNumber' | 'MAX_VALUE' | 'MIN_VALUE'
214
214
  >('=');
215
215
 
216
216
  const isFnOrUndefined = (
@@ -292,7 +292,7 @@ export namespace TsDataForgeInternals {
292
292
 
293
293
  castType: <N extends number>(x: N) => ElementType & N;
294
294
 
295
- clamp: TypeEq<MAX_VALUE | MIN_VALUE, undefined> extends true
295
+ fromNumber: TypeEq<MAX_VALUE | MIN_VALUE, undefined> extends true
296
296
  ? undefined
297
297
  : (x: number) => ElementType;
298
298
  }>;
@@ -337,7 +337,7 @@ export namespace TsDataForgeInternals {
337
337
  *
338
338
  * const quotient = intOps.div(six, intOps.castType(2));
339
339
  *
340
- * const roundedClamp = intOps.clamp(1.5);
340
+ * const coerced = intOps.fromNumber(1.5);
341
341
  *
342
342
  * const randomValue = intOps.random();
343
343
  *
@@ -349,7 +349,7 @@ export namespace TsDataForgeInternals {
349
349
  *
350
350
  * assert.isTrue(quotient === 3);
351
351
  *
352
- * assert.isTrue(roundedClamp === 2);
352
+ * assert.isTrue(coerced === 2);
353
353
  *
354
354
  * assert.isTrue(Number.isSafeInteger(randomValue));
355
355
  * ```
@@ -396,7 +396,7 @@ export namespace TsDataForgeInternals {
396
396
 
397
397
  const castType = castTypeImpl<ElementType>(is, typeNameInMessage);
398
398
 
399
- const clamp: ((a: number) => ElementType) | undefined = pipe(
399
+ const fromNumber: ((a: number) => ElementType) | undefined = pipe(
400
400
  clampFnOrUndefined(MIN_VALUE, MAX_VALUE),
401
401
  ).mapNullable(
402
402
  (cl) =>
@@ -404,7 +404,7 @@ export namespace TsDataForgeInternals {
404
404
  castType(Math.round(cl(x))),
405
405
  ).value;
406
406
 
407
- const clampOrCastFn: (a: number) => ElementType = clamp ?? castType;
407
+ const clampOrCastFn: (a: number) => ElementType = fromNumber ?? castType;
408
408
 
409
409
  const abs = (x: ElementTypeWithSmallInt): ToNonNegative<ElementType> =>
410
410
  // eslint-disable-next-line total-functions/no-unsafe-type-assertion
@@ -488,9 +488,9 @@ export namespace TsDataForgeInternals {
488
488
  randomNonZero,
489
489
  castType,
490
490
 
491
- clamp:
491
+ fromNumber:
492
492
  // eslint-disable-next-line total-functions/no-unsafe-type-assertion
493
- clamp as TypeEq<MAX_VALUE | MIN_VALUE, undefined> extends true
493
+ fromNumber as TypeEq<MAX_VALUE | MIN_VALUE, undefined> extends true
494
494
  ? undefined
495
495
  : (x: number) => ElementType,
496
496
  } as const;
@@ -519,7 +519,7 @@ export namespace TsDataForgeInternals {
519
519
 
520
520
  castType: <N extends number>(x: N) => ElementType & N;
521
521
 
522
- clamp: TypeEq<MAX_VALUE | MIN_VALUE, undefined> extends true
522
+ fromNumber: TypeEq<MAX_VALUE | MIN_VALUE, undefined> extends true
523
523
  ? undefined
524
524
  : (x: number) => ElementType;
525
525
  }>;
@@ -560,7 +560,7 @@ export namespace TsDataForgeInternals {
560
560
  *
561
561
  * const ratio = floatOps.div(sum, floatOps.castType(10));
562
562
  *
563
- * const clamped = floatOps.clamp(0);
563
+ * const coerced = floatOps.fromNumber(0);
564
564
  *
565
565
  * const boundedRandom = floatOps.random(
566
566
  * floatOps.castType(10),
@@ -573,7 +573,7 @@ export namespace TsDataForgeInternals {
573
573
  *
574
574
  * assert.isTrue(ratio === 5);
575
575
  *
576
- * assert.isTrue(clamped >= Number.MIN_VALUE);
576
+ * assert.isTrue(coerced >= Number.MIN_VALUE);
577
577
  *
578
578
  * assert.isTrue(boundedRandom >= 10 && boundedRandom <= 20);
579
579
  *
@@ -615,7 +615,7 @@ export namespace TsDataForgeInternals {
615
615
 
616
616
  const castType = castTypeImpl<ElementType>(is, typeNameInMessage);
617
617
 
618
- const clamp: ((a: number) => ElementType) | undefined = pipe(
618
+ const fromNumber: ((a: number) => ElementType) | undefined = pipe(
619
619
  clampFnOrUndefined(MIN_VALUE, MAX_VALUE),
620
620
  ).mapNullable(
621
621
  (cl) =>
@@ -623,7 +623,7 @@ export namespace TsDataForgeInternals {
623
623
  castType(cl(x)),
624
624
  ).value;
625
625
 
626
- const clampOrCastFn: (a: number) => ElementType = clamp ?? castType;
626
+ const clampOrCastFn: (a: number) => ElementType = fromNumber ?? castType;
627
627
 
628
628
  const abs = (x: ElementType): ToNonNegative<ElementType> =>
629
629
  // eslint-disable-next-line total-functions/no-unsafe-type-assertion
@@ -687,7 +687,10 @@ export namespace TsDataForgeInternals {
687
687
  castType,
688
688
 
689
689
  // eslint-disable-next-line total-functions/no-unsafe-type-assertion
690
- clamp: clamp as TypeEq<MAX_VALUE | MIN_VALUE, undefined> extends true
690
+ fromNumber: fromNumber as TypeEq<
691
+ MAX_VALUE | MIN_VALUE,
692
+ undefined
693
+ > extends true
691
694
  ? undefined
692
695
  : (x: number) => ElementType,
693
696
  } as const;