ts-data-forge 1.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 (143) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +534 -0
  3. package/package.json +101 -0
  4. package/src/array/array-utils-creation.test.mts +443 -0
  5. package/src/array/array-utils-modification.test.mts +197 -0
  6. package/src/array/array-utils-overload-type-error.test.mts +149 -0
  7. package/src/array/array-utils-reducing-value.test.mts +425 -0
  8. package/src/array/array-utils-search.test.mts +169 -0
  9. package/src/array/array-utils-set-op.test.mts +335 -0
  10. package/src/array/array-utils-slice-clamped.test.mts +113 -0
  11. package/src/array/array-utils-slicing.test.mts +316 -0
  12. package/src/array/array-utils-transformation.test.mts +790 -0
  13. package/src/array/array-utils-validation.test.mts +492 -0
  14. package/src/array/array-utils.mts +4000 -0
  15. package/src/array/array.test.mts +146 -0
  16. package/src/array/index.mts +2 -0
  17. package/src/array/tuple-utils.mts +519 -0
  18. package/src/array/tuple-utils.test.mts +518 -0
  19. package/src/collections/imap-mapped.mts +801 -0
  20. package/src/collections/imap-mapped.test.mts +860 -0
  21. package/src/collections/imap.mts +651 -0
  22. package/src/collections/imap.test.mts +932 -0
  23. package/src/collections/index.mts +6 -0
  24. package/src/collections/iset-mapped.mts +889 -0
  25. package/src/collections/iset-mapped.test.mts +1187 -0
  26. package/src/collections/iset.mts +682 -0
  27. package/src/collections/iset.test.mts +1084 -0
  28. package/src/collections/queue.mts +390 -0
  29. package/src/collections/queue.test.mts +282 -0
  30. package/src/collections/stack.mts +423 -0
  31. package/src/collections/stack.test.mts +225 -0
  32. package/src/expect-type.mts +206 -0
  33. package/src/functional/index.mts +4 -0
  34. package/src/functional/match.mts +300 -0
  35. package/src/functional/match.test.mts +177 -0
  36. package/src/functional/optional.mts +733 -0
  37. package/src/functional/optional.test.mts +619 -0
  38. package/src/functional/pipe.mts +212 -0
  39. package/src/functional/pipe.test.mts +85 -0
  40. package/src/functional/result.mts +1134 -0
  41. package/src/functional/result.test.mts +777 -0
  42. package/src/globals.d.mts +38 -0
  43. package/src/guard/has-key.mts +119 -0
  44. package/src/guard/has-key.test.mts +219 -0
  45. package/src/guard/index.mts +7 -0
  46. package/src/guard/is-non-empty-string.mts +108 -0
  47. package/src/guard/is-non-empty-string.test.mts +91 -0
  48. package/src/guard/is-non-null-object.mts +106 -0
  49. package/src/guard/is-non-null-object.test.mts +90 -0
  50. package/src/guard/is-primitive.mts +165 -0
  51. package/src/guard/is-primitive.test.mts +102 -0
  52. package/src/guard/is-record.mts +153 -0
  53. package/src/guard/is-record.test.mts +112 -0
  54. package/src/guard/is-type.mts +450 -0
  55. package/src/guard/is-type.test.mts +496 -0
  56. package/src/guard/key-is-in.mts +163 -0
  57. package/src/guard/key-is-in.test.mts +19 -0
  58. package/src/index.mts +10 -0
  59. package/src/iterator/index.mts +1 -0
  60. package/src/iterator/range.mts +120 -0
  61. package/src/iterator/range.test.mts +33 -0
  62. package/src/json/index.mts +1 -0
  63. package/src/json/json.mts +711 -0
  64. package/src/json/json.test.mts +628 -0
  65. package/src/number/branded-types/finite-number.mts +354 -0
  66. package/src/number/branded-types/finite-number.test.mts +135 -0
  67. package/src/number/branded-types/index.mts +26 -0
  68. package/src/number/branded-types/int.mts +278 -0
  69. package/src/number/branded-types/int.test.mts +140 -0
  70. package/src/number/branded-types/int16.mts +192 -0
  71. package/src/number/branded-types/int16.test.mts +170 -0
  72. package/src/number/branded-types/int32.mts +193 -0
  73. package/src/number/branded-types/int32.test.mts +170 -0
  74. package/src/number/branded-types/non-negative-finite-number.mts +223 -0
  75. package/src/number/branded-types/non-negative-finite-number.test.mts +188 -0
  76. package/src/number/branded-types/non-negative-int16.mts +187 -0
  77. package/src/number/branded-types/non-negative-int16.test.mts +201 -0
  78. package/src/number/branded-types/non-negative-int32.mts +187 -0
  79. package/src/number/branded-types/non-negative-int32.test.mts +204 -0
  80. package/src/number/branded-types/non-zero-finite-number.mts +229 -0
  81. package/src/number/branded-types/non-zero-finite-number.test.mts +198 -0
  82. package/src/number/branded-types/non-zero-int.mts +167 -0
  83. package/src/number/branded-types/non-zero-int.test.mts +177 -0
  84. package/src/number/branded-types/non-zero-int16.mts +196 -0
  85. package/src/number/branded-types/non-zero-int16.test.mts +195 -0
  86. package/src/number/branded-types/non-zero-int32.mts +196 -0
  87. package/src/number/branded-types/non-zero-int32.test.mts +197 -0
  88. package/src/number/branded-types/non-zero-safe-int.mts +196 -0
  89. package/src/number/branded-types/non-zero-safe-int.test.mts +232 -0
  90. package/src/number/branded-types/non-zero-uint16.mts +189 -0
  91. package/src/number/branded-types/non-zero-uint16.test.mts +199 -0
  92. package/src/number/branded-types/non-zero-uint32.mts +189 -0
  93. package/src/number/branded-types/non-zero-uint32.test.mts +199 -0
  94. package/src/number/branded-types/positive-finite-number.mts +241 -0
  95. package/src/number/branded-types/positive-finite-number.test.mts +204 -0
  96. package/src/number/branded-types/positive-int.mts +304 -0
  97. package/src/number/branded-types/positive-int.test.mts +176 -0
  98. package/src/number/branded-types/positive-int16.mts +188 -0
  99. package/src/number/branded-types/positive-int16.test.mts +197 -0
  100. package/src/number/branded-types/positive-int32.mts +188 -0
  101. package/src/number/branded-types/positive-int32.test.mts +197 -0
  102. package/src/number/branded-types/positive-safe-int.mts +187 -0
  103. package/src/number/branded-types/positive-safe-int.test.mts +210 -0
  104. package/src/number/branded-types/positive-uint16.mts +188 -0
  105. package/src/number/branded-types/positive-uint16.test.mts +203 -0
  106. package/src/number/branded-types/positive-uint32.mts +188 -0
  107. package/src/number/branded-types/positive-uint32.test.mts +203 -0
  108. package/src/number/branded-types/safe-int.mts +291 -0
  109. package/src/number/branded-types/safe-int.test.mts +170 -0
  110. package/src/number/branded-types/safe-uint.mts +187 -0
  111. package/src/number/branded-types/safe-uint.test.mts +176 -0
  112. package/src/number/branded-types/uint.mts +179 -0
  113. package/src/number/branded-types/uint.test.mts +158 -0
  114. package/src/number/branded-types/uint16.mts +186 -0
  115. package/src/number/branded-types/uint16.test.mts +170 -0
  116. package/src/number/branded-types/uint32.mts +218 -0
  117. package/src/number/branded-types/uint32.test.mts +170 -0
  118. package/src/number/enum/index.mts +2 -0
  119. package/src/number/enum/int8.mts +344 -0
  120. package/src/number/enum/int8.test.mts +180 -0
  121. package/src/number/enum/uint8.mts +293 -0
  122. package/src/number/enum/uint8.test.mts +164 -0
  123. package/src/number/index.mts +4 -0
  124. package/src/number/num.mts +604 -0
  125. package/src/number/num.test.mts +242 -0
  126. package/src/number/refined-number-utils.mts +566 -0
  127. package/src/object/index.mts +1 -0
  128. package/src/object/object.mts +447 -0
  129. package/src/object/object.test.mts +124 -0
  130. package/src/others/cast-mutable.mts +113 -0
  131. package/src/others/cast-readonly.mts +192 -0
  132. package/src/others/cast-readonly.test.mts +89 -0
  133. package/src/others/if-then.mts +98 -0
  134. package/src/others/if-then.test.mts +75 -0
  135. package/src/others/index.mts +7 -0
  136. package/src/others/map-nullable.mts +172 -0
  137. package/src/others/map-nullable.test.mts +297 -0
  138. package/src/others/memoize-function.mts +196 -0
  139. package/src/others/memoize-function.test.mts +168 -0
  140. package/src/others/tuple.mts +160 -0
  141. package/src/others/tuple.test.mts +11 -0
  142. package/src/others/unknown-to-string.mts +215 -0
  143. package/src/others/unknown-to-string.test.mts +114 -0
@@ -0,0 +1,278 @@
1
+ import { expectType } from '../../expect-type.mjs';
2
+ import { TsVerifiedInternals } from '../refined-number-utils.mjs';
3
+
4
+ type ElementType = Int;
5
+
6
+ const typeNameInMessage = 'an integer';
7
+
8
+ const {
9
+ abs,
10
+ min: min_,
11
+ max: max_,
12
+ pow,
13
+ add,
14
+ sub,
15
+ mul,
16
+ div,
17
+ random,
18
+ is,
19
+ castType,
20
+ } = TsVerifiedInternals.RefinedNumberUtils.operatorsForInteger<
21
+ ElementType,
22
+ undefined,
23
+ undefined
24
+ >({
25
+ integerOrSafeInteger: 'Integer',
26
+ MIN_VALUE: undefined,
27
+ MAX_VALUE: undefined,
28
+ typeNameInMessage,
29
+ } as const);
30
+
31
+ /**
32
+ * Type guard that checks if a value is an integer.
33
+ *
34
+ * Returns `true` if the value is any integer (positive, negative, or zero),
35
+ * with no fractional component. This includes values outside the safe integer
36
+ * range, unlike SafeInt.
37
+ *
38
+ * @param value - The value to check
39
+ * @returns `true` if the value is an integer, `false` otherwise
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * isInt(5); // true
44
+ * isInt(-10); // true
45
+ * isInt(0); // true
46
+ * isInt(5.5); // false
47
+ * isInt(NaN); // false
48
+ * isInt(Infinity); // false
49
+ * ```
50
+ */
51
+ export const isInt = is;
52
+
53
+ /**
54
+ * Casts a number to an Int branded type.
55
+ *
56
+ * This function validates that the input is an integer and returns it with
57
+ * the Int brand. Throws a TypeError if the value has a fractional component
58
+ * or is not a finite number.
59
+ *
60
+ * @param value - The value to cast
61
+ * @returns The value as an Int branded type
62
+ * @throws {TypeError} If the value is not an integer
63
+ *
64
+ * @example
65
+ * ```typescript
66
+ * const x = asInt(5); // Int
67
+ * const y = asInt(-10); // Int
68
+ * const z = asInt(0); // Int
69
+ *
70
+ * // These throw TypeError:
71
+ * // asInt(5.5); // Not an integer
72
+ * // asInt(NaN); // Not a number
73
+ * // asInt(Infinity); // Not finite
74
+ * ```
75
+ */
76
+ export const asInt = castType;
77
+
78
+ /**
79
+ * Namespace providing type-safe operations for Int branded types.
80
+ *
81
+ * The Int type represents any integer value (no fractional component) without
82
+ * range restrictions. All operations preserve the integer constraint, using
83
+ * floor division for division operations.
84
+ *
85
+ * Unlike SafeInt, Int allows values outside the safe integer range
86
+ * (±2^53 - 1), but be aware that very large integers may lose precision
87
+ * in JavaScript's number type.
88
+ *
89
+ * @example
90
+ * ```typescript
91
+ * // Type validation
92
+ * Int.is(42); // true
93
+ * Int.is(3.14); // false
94
+ * Int.is(-0); // true (negative zero is an integer)
95
+ *
96
+ * // Basic arithmetic
97
+ * const a = asInt(10);
98
+ * const b = asInt(3);
99
+ *
100
+ * const sum = Int.add(a, b); // Int (13)
101
+ * const diff = Int.sub(a, b); // Int (7)
102
+ * const product = Int.mul(a, b); // Int (30)
103
+ * const quotient = Int.div(a, b); // Int (3) - floor division
104
+ * const power = Int.pow(a, b); // Int (1000)
105
+ *
106
+ * // Utility operations
107
+ * const absolute = Int.abs(asInt(-42)); // Int (42)
108
+ * const minimum = Int.min(a, b, asInt(5)); // Int (3)
109
+ * const maximum = Int.max(a, b, asInt(5)); // Int (10)
110
+ *
111
+ * // Random generation
112
+ * const die = Int.random(asInt(1), asInt(6)); // Random Int in [1, 6]
113
+ * ```
114
+ */
115
+ export const Int = {
116
+ /**
117
+ * Type guard that checks if a value is an integer.
118
+ *
119
+ * @param value - The value to check
120
+ * @returns `true` if the value is an integer, `false` otherwise
121
+ *
122
+ * @see {@link isInt} for usage examples
123
+ */
124
+ is,
125
+
126
+ /**
127
+ * Returns the absolute value of an integer.
128
+ *
129
+ * The result is always non-negative and maintains the Int brand.
130
+ * Note that Math.abs(Number.MIN_SAFE_INTEGER) exceeds Number.MAX_SAFE_INTEGER,
131
+ * so use SafeInt for guaranteed precision.
132
+ *
133
+ * @param a - The integer value
134
+ * @returns The absolute value as a non-negative Int
135
+ *
136
+ * @example
137
+ * ```typescript
138
+ * Int.abs(asInt(-5)); // Int (5)
139
+ * Int.abs(asInt(3)); // Int (3)
140
+ * Int.abs(asInt(-0)); // Int (0)
141
+ * ```
142
+ */
143
+ abs,
144
+
145
+ /**
146
+ * Returns the minimum value from a list of integers.
147
+ *
148
+ * @param values - The integers to compare (at least one required)
149
+ * @returns The smallest value as an Int
150
+ *
151
+ * @example
152
+ * ```typescript
153
+ * Int.min(asInt(5), asInt(3)); // Int (3)
154
+ * Int.min(asInt(-10), asInt(0), asInt(10)); // Int (-10)
155
+ * ```
156
+ */
157
+ min: min_,
158
+
159
+ /**
160
+ * Returns the maximum value from a list of integers.
161
+ *
162
+ * @param values - The integers to compare (at least one required)
163
+ * @returns The largest value as an Int
164
+ *
165
+ * @example
166
+ * ```typescript
167
+ * Int.max(asInt(5), asInt(3)); // Int (5)
168
+ * Int.max(asInt(-10), asInt(0), asInt(10)); // Int (10)
169
+ * ```
170
+ */
171
+ max: max_,
172
+
173
+ /**
174
+ * Generates a random integer within the specified range (inclusive).
175
+ *
176
+ * The range is inclusive on both ends, so random(1, 6) can return
177
+ * any of: 1, 2, 3, 4, 5, or 6.
178
+ *
179
+ * @param min - The minimum value (inclusive)
180
+ * @param max - The maximum value (inclusive)
181
+ * @returns A random Int in the range [min, max]
182
+ *
183
+ * @example
184
+ * ```typescript
185
+ * // Dice roll
186
+ * const d6 = Int.random(asInt(1), asInt(6));
187
+ *
188
+ * // Random array index
189
+ * const index = Int.random(asInt(0), asInt(array.length - 1));
190
+ *
191
+ * // Can generate negative values
192
+ * const temp = Int.random(asInt(-10), asInt(10));
193
+ * ```
194
+ */
195
+ random,
196
+
197
+ /**
198
+ * Raises an integer to a power.
199
+ * @param a - The base integer
200
+ * @param b - The exponent integer
201
+ * @returns `a ** b` as an Int
202
+ * @example
203
+ * ```typescript
204
+ * Int.pow(asInt(2), asInt(3)); // Int (8)
205
+ * ```
206
+ */
207
+ pow,
208
+
209
+ /**
210
+ * Adds two integers.
211
+ * @param a - First integer
212
+ * @param b - Second integer
213
+ * @returns `a + b` as an Int
214
+ * @example
215
+ * ```typescript
216
+ * Int.add(asInt(5), asInt(3)); // Int (8)
217
+ * ```
218
+ */
219
+ add,
220
+
221
+ /**
222
+ * Subtracts two integers.
223
+ * @param a - First integer
224
+ * @param b - Second integer
225
+ * @returns `a - b` as an Int
226
+ * @example
227
+ * ```typescript
228
+ * Int.sub(asInt(8), asInt(3)); // Int (5)
229
+ * ```
230
+ */
231
+ sub,
232
+
233
+ /**
234
+ * Multiplies two integers.
235
+ * @param a - First integer
236
+ * @param b - Second integer
237
+ * @returns `a * b` as an Int
238
+ * @example
239
+ * ```typescript
240
+ * Int.mul(asInt(4), asInt(3)); // Int (12)
241
+ * ```
242
+ */
243
+ mul,
244
+
245
+ /**
246
+ * Divides two integers using floor division.
247
+ *
248
+ * Performs mathematical floor division: `⌊a / b⌋`.
249
+ * The result is always an integer, rounding toward negative infinity.
250
+ *
251
+ * @param a - The dividend
252
+ * @param b - The divisor (must be non-zero)
253
+ * @returns The integer quotient as an Int
254
+ *
255
+ * @example
256
+ * ```typescript
257
+ * // Positive division
258
+ * Int.div(asInt(10), asInt(3)); // Int (3)
259
+ * Int.div(asInt(9), asInt(3)); // Int (3)
260
+ *
261
+ * // Negative division (rounds toward -∞)
262
+ * Int.div(asInt(-10), asInt(3)); // Int (-4)
263
+ * Int.div(asInt(10), asInt(-3)); // Int (-4)
264
+ * Int.div(asInt(-10), asInt(-3)); // Int (3)
265
+ * ```
266
+ */
267
+ div,
268
+ } as const;
269
+
270
+ expectType<
271
+ keyof typeof Int,
272
+ keyof TsVerifiedInternals.RefinedNumberUtils.NumberClass<ElementType, 'int'>
273
+ >('=');
274
+
275
+ expectType<
276
+ typeof Int,
277
+ TsVerifiedInternals.RefinedNumberUtils.NumberClass<ElementType, 'int'>
278
+ >('<=');
@@ -0,0 +1,140 @@
1
+ import { expectType } from '../../expect-type.mjs';
2
+ import { asInt, Int, isInt } from './int.mjs';
3
+ import { asNonZeroInt } from './non-zero-int.mjs';
4
+
5
+ describe('Int', () => {
6
+ describe('asInt', () => {
7
+ test('accepts valid integers', () => {
8
+ expect(() => asInt(0)).not.toThrow();
9
+ expect(() => asInt(1)).not.toThrow();
10
+ expect(() => asInt(-1)).not.toThrow();
11
+ expect(() => asInt(42)).not.toThrow();
12
+ expect(() => asInt(-42)).not.toThrow();
13
+ expect(() => asInt(Number.MAX_SAFE_INTEGER)).not.toThrow();
14
+ expect(() => asInt(Number.MIN_SAFE_INTEGER)).not.toThrow();
15
+ });
16
+
17
+ test('rejects non-integers', () => {
18
+ expect(() => asInt(Number.NaN)).toThrow(TypeError);
19
+ expect(() => asInt(Number.POSITIVE_INFINITY)).toThrow(TypeError);
20
+ expect(() => asInt(Number.NEGATIVE_INFINITY)).toThrow(TypeError);
21
+ expect(() => asInt(1.2)).toThrow(TypeError);
22
+ expect(() => asInt(-3.4)).toThrow(TypeError);
23
+ });
24
+
25
+ test('returns the same value for valid inputs', () => {
26
+ expect(asInt(5)).toBe(5);
27
+ expect(asInt(-10)).toBe(-10);
28
+ expect(asInt(0)).toBe(0);
29
+ });
30
+
31
+ test.each([
32
+ { name: 'Number.NaN', value: Number.NaN },
33
+ { name: 'Number.POSITIVE_INFINITY', value: Number.POSITIVE_INFINITY },
34
+ { name: 'Number.NEGATIVE_INFINITY', value: Number.NEGATIVE_INFINITY },
35
+ { name: '1.2', value: 1.2 },
36
+ { name: '-3.4', value: -3.4 },
37
+ ] as const)(`asInt($name) should throw a TypeError`, ({ value }) => {
38
+ expect(() => asInt(value)).toThrow(
39
+ new TypeError(`Expected an integer, got: ${value}`),
40
+ );
41
+ });
42
+ });
43
+
44
+ describe('isInt', () => {
45
+ test('correctly identifies integers', () => {
46
+ expect(isInt(0)).toBe(true);
47
+ expect(isInt(1)).toBe(true);
48
+ expect(isInt(-1)).toBe(true);
49
+ expect(isInt(42)).toBe(true);
50
+ expect(isInt(-42)).toBe(true);
51
+ expect(isInt(Number.MAX_SAFE_INTEGER)).toBe(true);
52
+ expect(isInt(Number.MIN_SAFE_INTEGER)).toBe(true);
53
+ });
54
+
55
+ test('correctly identifies non-integers', () => {
56
+ expect(isInt(Number.NaN)).toBe(false);
57
+ expect(isInt(Number.POSITIVE_INFINITY)).toBe(false);
58
+ expect(isInt(Number.NEGATIVE_INFINITY)).toBe(false);
59
+ expect(isInt(1.2)).toBe(false);
60
+ expect(isInt(-3.4)).toBe(false);
61
+ });
62
+ });
63
+
64
+ describe('Int.is', () => {
65
+ test('same as isInt function', () => {
66
+ expect(Int.is(5)).toBe(isInt(5));
67
+ expect(Int.is(1.5)).toBe(isInt(1.5));
68
+ expect(Int.is(-10)).toBe(isInt(-10));
69
+ });
70
+ });
71
+
72
+ describe('mathematical operations', () => {
73
+ const a = asInt(5);
74
+ const b = asInt(2);
75
+ const c = asInt(-3);
76
+
77
+ test('abs', () => {
78
+ expect(Int.abs(a)).toBe(5);
79
+ expect(Int.abs(c)).toBe(3);
80
+ expect(Int.abs(asInt(0))).toBe(0);
81
+ });
82
+
83
+ test('min and max', () => {
84
+ expect(Int.min(a, b)).toBe(2);
85
+ expect(Int.max(a, b)).toBe(5);
86
+ expect(Int.min(a, c)).toBe(-3);
87
+ expect(Int.max(a, c)).toBe(5);
88
+ });
89
+
90
+ test('add', () => {
91
+ expect(Int.add(a, b)).toBe(7);
92
+ expect(Int.add(a, c)).toBe(2);
93
+ });
94
+
95
+ test('sub', () => {
96
+ expect(Int.sub(a, b)).toBe(3);
97
+ expect(Int.sub(a, c)).toBe(8);
98
+ });
99
+
100
+ test('mul', () => {
101
+ expect(Int.mul(a, b)).toBe(10);
102
+ expect(Int.mul(a, c)).toBe(-15);
103
+ });
104
+
105
+ test('div (floor division)', () => {
106
+ expect(Int.div(a, asNonZeroInt(2))).toBe(2);
107
+ expect(Int.div(asInt(7), asNonZeroInt(3))).toBe(2);
108
+ expect(Int.div(asInt(-7), asNonZeroInt(3))).toBe(-3);
109
+ });
110
+
111
+ test('pow', () => {
112
+ expect(Int.pow(asInt(2), asInt(3))).toBe(8);
113
+ expect(Int.pow(asInt(3), asInt(2))).toBe(9);
114
+ expect(Int.pow(asInt(-2), asInt(3))).toBe(-8);
115
+ });
116
+ });
117
+
118
+ describe('random', () => {
119
+ test('generates integers within specified range', () => {
120
+ const min = -5;
121
+ const max = 10;
122
+
123
+ for (let i = 0; i < 10; i++) {
124
+ const result = Int.random(min, max);
125
+ expect(result).toBeGreaterThanOrEqual(min);
126
+ expect(result).toBeLessThanOrEqual(max);
127
+ expect(Int.is(result)).toBe(true);
128
+ expect(Number.isInteger(result)).toBe(true);
129
+ }
130
+ });
131
+ });
132
+
133
+ describe('type assertions', () => {
134
+ test('type relationships', () => {
135
+ expectType<Int, number>('<=');
136
+
137
+ expectTypeOf(asInt(5)).toExtend<Int>();
138
+ });
139
+ });
140
+ });
@@ -0,0 +1,192 @@
1
+ import { expectType } from '../../expect-type.mjs';
2
+ import { TsVerifiedInternals } from '../refined-number-utils.mjs';
3
+
4
+ type ElementType = Int16;
5
+
6
+ const typeNameInMessage = 'an integer in [-2^15, 2^15)';
7
+
8
+ const {
9
+ MIN_VALUE,
10
+ MAX_VALUE,
11
+ min: min_,
12
+ max: max_,
13
+ abs,
14
+ pow,
15
+ add,
16
+ sub,
17
+ mul,
18
+ div,
19
+ random,
20
+ is,
21
+ castType,
22
+ clamp,
23
+ } = TsVerifiedInternals.RefinedNumberUtils.operatorsForInteger<
24
+ ElementType,
25
+ number,
26
+ number
27
+ >({
28
+ integerOrSafeInteger: 'SafeInteger',
29
+ MIN_VALUE: -(2 ** 15),
30
+ MAX_VALUE: 2 ** 15 - 1,
31
+ typeNameInMessage,
32
+ } as const);
33
+
34
+ /**
35
+ * Checks if a number is an Int16 (16-bit signed integer in the range [-2^15, 2^15)).
36
+ * @param value The value to check.
37
+ * @returns `true` if the value is an Int16, `false` otherwise.
38
+ */
39
+ export const isInt16 = is;
40
+
41
+ /**
42
+ * Casts a number to an Int16 type.
43
+ * @param value The value to cast.
44
+ * @returns The value as an Int16 type.
45
+ * @throws {TypeError} If the value is not an integer in [-2^15, 2^15).
46
+ * @example
47
+ * ```typescript
48
+ * const x = asInt16(1000); // Int16
49
+ * const y = asInt16(-5000); // Int16
50
+ * // asInt16(50000); // throws TypeError
51
+ * // asInt16(1.5); // throws TypeError
52
+ * ```
53
+ */
54
+ export const asInt16 = castType;
55
+
56
+ /**
57
+ * Namespace providing type-safe arithmetic operations for 16-bit signed integers.
58
+ *
59
+ * All operations automatically clamp results to the valid Int16 range [-32768, 32767].
60
+ * This ensures that all arithmetic maintains the 16-bit signed integer constraint.
61
+ *
62
+ * @example
63
+ * ```typescript
64
+ * const a = asInt16(30000);
65
+ * const b = asInt16(5000);
66
+ *
67
+ * // Arithmetic operations with automatic clamping
68
+ * const sum = Int16.add(a, b); // Int16 (32767 - clamped to MAX_VALUE)
69
+ * const diff = Int16.sub(a, b); // Int16 (25000)
70
+ * const product = Int16.mul(a, b); // Int16 (32767 - clamped due to overflow)
71
+ *
72
+ * // Range operations
73
+ * const clamped = Int16.clamp(100000); // Int16 (32767)
74
+ * const minimum = Int16.min(a, b); // Int16 (5000)
75
+ * const maximum = Int16.max(a, b); // Int16 (30000)
76
+ *
77
+ * // Range constants
78
+ * const range = Int16.MAX_VALUE - Int16.MIN_VALUE + 1; // 65536
79
+ * ```
80
+ */
81
+ export const Int16 = {
82
+ /**
83
+ * Type guard to check if a value is an Int16.
84
+ * @param value The value to check.
85
+ * @returns `true` if the value is a 16-bit signed integer, `false` otherwise.
86
+ */
87
+ is,
88
+
89
+ /**
90
+ * The minimum value for a 16-bit signed integer.
91
+ * @readonly
92
+ */
93
+ MIN_VALUE,
94
+
95
+ /**
96
+ * The maximum value for a 16-bit signed integer.
97
+ * @readonly
98
+ */
99
+ MAX_VALUE,
100
+
101
+ /**
102
+ * Returns the absolute value of a 16-bit signed integer.
103
+ * @param a The Int16 value.
104
+ * @returns The absolute value as an Int16, clamped to valid range.
105
+ */
106
+ abs,
107
+
108
+ /**
109
+ * Returns the smaller of two Int16 values.
110
+ * @param a The first Int16.
111
+ * @param b The second Int16.
112
+ * @returns The minimum value as an Int16.
113
+ */
114
+ min: min_,
115
+
116
+ /**
117
+ * Returns the larger of two Int16 values.
118
+ * @param a The first Int16.
119
+ * @param b The second Int16.
120
+ * @returns The maximum value as an Int16.
121
+ */
122
+ max: max_,
123
+
124
+ /**
125
+ * Clamps a number to the Int16 range.
126
+ * @param value The number to clamp.
127
+ * @returns The value clamped to [-32768, 32767] as an Int16.
128
+ */
129
+ clamp,
130
+
131
+ /**
132
+ * Generates a random Int16 value within the valid range.
133
+ * @returns A random Int16 between MIN_VALUE and MAX_VALUE.
134
+ */
135
+ random,
136
+
137
+ /**
138
+ * Raises an Int16 to the power of another Int16.
139
+ * @param a The base Int16.
140
+ * @param b The exponent Int16.
141
+ * @returns `a ** b` clamped to [-32768, 32767] as an Int16.
142
+ */
143
+ pow,
144
+
145
+ /**
146
+ * Adds two Int16 values.
147
+ * @param a The first Int16.
148
+ * @param b The second Int16.
149
+ * @returns `a + b` clamped to [-32768, 32767] as an Int16.
150
+ */
151
+ add,
152
+
153
+ /**
154
+ * Subtracts one Int16 from another.
155
+ * @param a The minuend Int16.
156
+ * @param b The subtrahend Int16.
157
+ * @returns `a - b` clamped to [-32768, 32767] as an Int16.
158
+ */
159
+ sub,
160
+
161
+ /**
162
+ * Multiplies two Int16 values.
163
+ * @param a The first Int16.
164
+ * @param b The second Int16.
165
+ * @returns `a * b` clamped to [-32768, 32767] as an Int16.
166
+ */
167
+ mul,
168
+
169
+ /**
170
+ * Divides one Int16 by another using floor division.
171
+ * @param a The dividend Int16.
172
+ * @param b The divisor Int16.
173
+ * @returns `⌊a / b⌋` clamped to [-32768, 32767] as an Int16.
174
+ */
175
+ div,
176
+ } as const;
177
+
178
+ expectType<
179
+ keyof typeof Int16,
180
+ keyof TsVerifiedInternals.RefinedNumberUtils.NumberClass<
181
+ ElementType,
182
+ 'int' | 'range'
183
+ >
184
+ >('=');
185
+
186
+ expectType<
187
+ typeof Int16,
188
+ TsVerifiedInternals.RefinedNumberUtils.NumberClass<
189
+ ElementType,
190
+ 'int' | 'range'
191
+ >
192
+ >('<=');