ts-data-forge 6.13.1 → 7.0.1
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.
- package/README.md +2 -2
- package/dist/array/impl/array-utils-creation.d.mts.map +1 -1
- package/dist/array/impl/array-utils-creation.mjs +1 -1
- package/dist/array/impl/array-utils-creation.mjs.map +1 -1
- package/dist/array/impl/array-utils-iterators.mjs +7 -1
- package/dist/array/impl/array-utils-iterators.mjs.map +1 -1
- package/dist/array/impl/array-utils-modification.mjs +6 -0
- package/dist/array/impl/array-utils-modification.mjs.map +1 -1
- package/dist/array/impl/array-utils-reducing-value.d.mts +1 -1
- package/dist/array/impl/array-utils-reducing-value.d.mts.map +1 -1
- package/dist/array/impl/array-utils-reducing-value.mjs +6 -1
- package/dist/array/impl/array-utils-reducing-value.mjs.map +1 -1
- package/dist/array/impl/array-utils-search.d.mts +0 -2
- package/dist/array/impl/array-utils-search.d.mts.map +1 -1
- package/dist/array/impl/array-utils-search.mjs +6 -0
- package/dist/array/impl/array-utils-search.mjs.map +1 -1
- package/dist/array/impl/array-utils-set-op.d.mts.map +1 -1
- package/dist/array/impl/array-utils-set-op.mjs +0 -1
- package/dist/array/impl/array-utils-set-op.mjs.map +1 -1
- package/dist/array/impl/array-utils-slice-clamped.mjs +6 -0
- package/dist/array/impl/array-utils-slice-clamped.mjs.map +1 -1
- package/dist/array/impl/array-utils-slicing.mjs +6 -0
- package/dist/array/impl/array-utils-slicing.mjs.map +1 -1
- package/dist/array/impl/array-utils-transformation.d.mts +1 -1
- package/dist/array/impl/array-utils-transformation.d.mts.map +1 -1
- package/dist/array/impl/array-utils-transformation.mjs +8 -4
- package/dist/array/impl/array-utils-transformation.mjs.map +1 -1
- package/dist/array/impl/array-utils-validation.d.mts.map +1 -1
- package/dist/array/impl/array-utils-validation.mjs +9 -9
- package/dist/array/impl/array-utils-validation.mjs.map +1 -1
- package/dist/collections/imap-mapped.d.mts +622 -3
- package/dist/collections/imap-mapped.d.mts.map +1 -1
- package/dist/collections/imap-mapped.mjs +117 -18
- package/dist/collections/imap-mapped.mjs.map +1 -1
- package/dist/collections/imap.d.mts +3 -3
- package/dist/collections/imap.d.mts.map +1 -1
- package/dist/collections/imap.mjs +12 -5
- package/dist/collections/imap.mjs.map +1 -1
- package/dist/collections/iset-mapped.d.mts +4 -4
- package/dist/collections/iset-mapped.d.mts.map +1 -1
- package/dist/collections/iset-mapped.mjs +14 -4
- package/dist/collections/iset-mapped.mjs.map +1 -1
- package/dist/collections/iset.d.mts +2 -2
- package/dist/collections/iset.d.mts.map +1 -1
- package/dist/collections/iset.mjs +11 -2
- package/dist/collections/iset.mjs.map +1 -1
- package/dist/collections/queue.mjs +26 -20
- package/dist/collections/queue.mjs.map +1 -1
- package/dist/collections/stack.mjs +23 -17
- package/dist/collections/stack.mjs.map +1 -1
- package/dist/entry-point.mjs +6 -0
- package/dist/entry-point.mjs.map +1 -1
- package/dist/functional/optional/impl/optional-flat-map.d.mts +2 -2
- package/dist/functional/pipe.d.mts.map +1 -1
- package/dist/functional/pipe.mjs.map +1 -1
- package/dist/functional/result/impl/result-flat-map.d.mts +2 -2
- package/dist/functional/ternary-result/impl/ternary-result-flat-map.d.mts +5 -3
- package/dist/functional/ternary-result/impl/ternary-result-flat-map.d.mts.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-flat-map.mjs.map +1 -1
- package/dist/guard/has-key.d.mts.map +1 -1
- package/dist/guard/has-key.mjs +1 -3
- package/dist/guard/has-key.mjs.map +1 -1
- package/dist/guard/is-non-null-object.d.mts.map +1 -1
- package/dist/guard/is-non-null-object.mjs +1 -3
- package/dist/guard/is-non-null-object.mjs.map +1 -1
- package/dist/guard/key-is-in.d.mts.map +1 -1
- package/dist/guard/key-is-in.mjs +1 -3
- package/dist/guard/key-is-in.mjs.map +1 -1
- package/dist/index.mjs +6 -0
- package/dist/index.mjs.map +1 -1
- package/dist/iterator/range.mjs +6 -0
- package/dist/iterator/range.mjs.map +1 -1
- package/dist/json/json.mjs +11 -7
- package/dist/json/json.mjs.map +1 -1
- package/dist/number/branded-types/finite-number.d.mts +1 -1
- package/dist/number/branded-types/index.d.mts +6 -0
- package/dist/number/branded-types/index.d.mts.map +1 -1
- package/dist/number/branded-types/index.mjs +6 -0
- package/dist/number/branded-types/index.mjs.map +1 -1
- package/dist/number/branded-types/int.d.mts +1 -2
- package/dist/number/branded-types/int.d.mts.map +1 -1
- package/dist/number/branded-types/int16.d.mts +2 -3
- package/dist/number/branded-types/int16.d.mts.map +1 -1
- package/dist/number/branded-types/int32.d.mts +2 -3
- package/dist/number/branded-types/int32.d.mts.map +1 -1
- package/dist/number/branded-types/negative-finite-number.d.mts +143 -0
- package/dist/number/branded-types/negative-finite-number.d.mts.map +1 -0
- package/dist/number/branded-types/negative-finite-number.mjs +156 -0
- package/dist/number/branded-types/negative-finite-number.mjs.map +1 -0
- package/dist/number/branded-types/negative-int.d.mts +120 -0
- package/dist/number/branded-types/negative-int.d.mts.map +1 -0
- package/dist/number/branded-types/negative-int.mjs +125 -0
- package/dist/number/branded-types/negative-int.mjs.map +1 -0
- package/dist/number/branded-types/negative-safe-int.d.mts +132 -0
- package/dist/number/branded-types/negative-safe-int.d.mts.map +1 -0
- package/dist/number/branded-types/negative-safe-int.mjs +136 -0
- package/dist/number/branded-types/negative-safe-int.mjs.map +1 -0
- package/dist/number/branded-types/non-negative-finite-number.d.mts +1 -1
- package/dist/number/branded-types/non-negative-int16.d.mts +1 -1
- package/dist/number/branded-types/non-negative-int32.d.mts +1 -1
- package/dist/number/branded-types/non-positive-finite-number.d.mts +130 -0
- package/dist/number/branded-types/non-positive-finite-number.d.mts.map +1 -0
- package/dist/number/branded-types/non-positive-finite-number.mjs +134 -0
- package/dist/number/branded-types/non-positive-finite-number.mjs.map +1 -0
- package/dist/number/branded-types/non-positive-int.d.mts +224 -0
- package/dist/number/branded-types/non-positive-int.d.mts.map +1 -0
- package/dist/number/branded-types/non-positive-int.mjs +222 -0
- package/dist/number/branded-types/non-positive-int.mjs.map +1 -0
- package/dist/number/branded-types/non-positive-safe-int.d.mts +119 -0
- package/dist/number/branded-types/non-positive-safe-int.d.mts.map +1 -0
- package/dist/number/branded-types/non-positive-safe-int.mjs +116 -0
- package/dist/number/branded-types/non-positive-safe-int.mjs.map +1 -0
- package/dist/number/branded-types/non-zero-finite-number.d.mts +5 -17
- package/dist/number/branded-types/non-zero-finite-number.d.mts.map +1 -1
- package/dist/number/branded-types/non-zero-finite-number.mjs +5 -17
- package/dist/number/branded-types/non-zero-finite-number.mjs.map +1 -1
- package/dist/number/branded-types/non-zero-int.d.mts +5 -33
- package/dist/number/branded-types/non-zero-int.d.mts.map +1 -1
- package/dist/number/branded-types/non-zero-int.mjs +5 -25
- package/dist/number/branded-types/non-zero-int.mjs.map +1 -1
- package/dist/number/branded-types/non-zero-int16.d.mts +6 -43
- package/dist/number/branded-types/non-zero-int16.d.mts.map +1 -1
- package/dist/number/branded-types/non-zero-int16.mjs +5 -25
- package/dist/number/branded-types/non-zero-int16.mjs.map +1 -1
- package/dist/number/branded-types/non-zero-int32.d.mts +6 -39
- package/dist/number/branded-types/non-zero-int32.d.mts.map +1 -1
- package/dist/number/branded-types/non-zero-int32.mjs +5 -25
- package/dist/number/branded-types/non-zero-int32.mjs.map +1 -1
- package/dist/number/branded-types/non-zero-safe-int.d.mts +5 -37
- package/dist/number/branded-types/non-zero-safe-int.d.mts.map +1 -1
- package/dist/number/branded-types/non-zero-safe-int.mjs +7 -30
- package/dist/number/branded-types/non-zero-safe-int.mjs.map +1 -1
- package/dist/number/branded-types/non-zero-uint16.d.mts +6 -33
- package/dist/number/branded-types/non-zero-uint16.d.mts.map +1 -1
- package/dist/number/branded-types/non-zero-uint16.mjs +5 -17
- package/dist/number/branded-types/non-zero-uint16.mjs.map +1 -1
- package/dist/number/branded-types/non-zero-uint32.d.mts +6 -31
- package/dist/number/branded-types/non-zero-uint32.d.mts.map +1 -1
- package/dist/number/branded-types/non-zero-uint32.mjs +5 -17
- package/dist/number/branded-types/non-zero-uint32.mjs.map +1 -1
- package/dist/number/branded-types/positive-finite-number.d.mts +4 -2
- package/dist/number/branded-types/positive-finite-number.d.mts.map +1 -1
- package/dist/number/branded-types/positive-int.d.mts +4 -2
- package/dist/number/branded-types/positive-int.d.mts.map +1 -1
- package/dist/number/branded-types/positive-int16.d.mts +4 -2
- package/dist/number/branded-types/positive-int16.d.mts.map +1 -1
- package/dist/number/branded-types/positive-int32.d.mts +4 -2
- package/dist/number/branded-types/positive-int32.d.mts.map +1 -1
- package/dist/number/branded-types/positive-safe-int.d.mts +4 -2
- package/dist/number/branded-types/positive-safe-int.d.mts.map +1 -1
- package/dist/number/branded-types/positive-safe-int.mjs +1 -1
- package/dist/number/branded-types/positive-uint16.d.mts +4 -2
- package/dist/number/branded-types/positive-uint16.d.mts.map +1 -1
- package/dist/number/branded-types/positive-uint32.d.mts +4 -2
- package/dist/number/branded-types/positive-uint32.d.mts.map +1 -1
- package/dist/number/branded-types/safe-int.d.mts +1 -2
- package/dist/number/branded-types/safe-int.d.mts.map +1 -1
- package/dist/number/branded-types/safe-int.mjs +2 -2
- package/dist/number/branded-types/safe-uint.d.mts +1 -1
- package/dist/number/branded-types/safe-uint.mjs +1 -1
- package/dist/number/branded-types/uint.d.mts +1 -1
- package/dist/number/branded-types/uint16.d.mts +1 -1
- package/dist/number/branded-types/uint32.d.mts +1 -1
- package/dist/number/index.d.mts +1 -0
- package/dist/number/index.d.mts.map +1 -1
- package/dist/number/index.mjs +6 -0
- package/dist/number/index.mjs.map +1 -1
- package/dist/number/num-arithmetic-types.d.mts +74 -0
- package/dist/number/num-arithmetic-types.d.mts.map +1 -0
- package/dist/number/num-arithmetic-types.mjs +2 -0
- package/dist/number/num-arithmetic-types.mjs.map +1 -0
- package/dist/number/num.d.mts +53 -9
- package/dist/number/num.d.mts.map +1 -1
- package/dist/number/num.mjs +67 -15
- package/dist/number/num.mjs.map +1 -1
- package/dist/number/refined-number-utils.d.mts +12 -9
- package/dist/number/refined-number-utils.d.mts.map +1 -1
- package/dist/number/refined-number-utils.mjs.map +1 -1
- package/dist/object/object.mjs +7 -1
- package/dist/object/object.mjs.map +1 -1
- package/dist/others/fast-deep-equal.d.mts.map +1 -1
- package/dist/others/fast-deep-equal.mjs +0 -1
- package/dist/others/fast-deep-equal.mjs.map +1 -1
- package/dist/others/unknown-to-string.mjs +2 -2
- package/dist/others/unknown-to-string.mjs.map +1 -1
- package/package.json +6 -6
- package/src/array/impl/array-utils-creation.mts +1 -1
- package/src/array/impl/array-utils-iterators.mts +1 -1
- package/src/array/impl/array-utils-reducing-value.mts +1 -2
- package/src/array/impl/array-utils-search.mts +0 -2
- package/src/array/impl/array-utils-set-op.mts +0 -1
- package/src/array/impl/array-utils-transformation.mts +8 -6
- package/src/array/impl/array-utils-validation.mts +1 -5
- package/src/collections/imap-mapped.mts +696 -34
- package/src/collections/imap-mapped.test.mts +61 -13
- package/src/collections/imap.mts +20 -9
- package/src/collections/imap.test.mts +9 -8
- package/src/collections/iset-mapped.mts +18 -10
- package/src/collections/iset-mapped.test.mts +6 -1
- package/src/collections/iset.mts +11 -4
- package/src/collections/iset.test.mts +6 -8
- package/src/collections/queue.mts +32 -32
- package/src/collections/stack.mts +26 -26
- package/src/functional/optional/impl/optional-flat-map.mts +2 -2
- package/src/functional/optional.test.mts +6 -4
- package/src/functional/pipe.mts +0 -1
- package/src/functional/pipe.test.mts +2 -1
- package/src/functional/result/impl/result-flat-map.mts +2 -2
- package/src/functional/result.test.mts +3 -2
- package/src/functional/ternary-result/impl/ternary-result-flat-map.mts +5 -3
- package/src/functional/ternary-result.test.mts +8 -3
- package/src/guard/has-key.mts +1 -3
- package/src/guard/is-non-null-object.mts +0 -1
- package/src/guard/key-is-in.mts +1 -3
- package/src/json/json.mts +5 -8
- package/src/json/json.test.mts +2 -2
- package/src/number/branded-types/index.mts +6 -0
- package/src/number/branded-types/negative-finite-number.mts +210 -0
- package/src/number/branded-types/negative-finite-number.test.mts +172 -0
- package/src/number/branded-types/negative-int.mts +160 -0
- package/src/number/branded-types/negative-int.test.mts +146 -0
- package/src/number/branded-types/negative-safe-int.mts +173 -0
- package/src/number/branded-types/negative-safe-int.test.mts +120 -0
- package/src/number/branded-types/non-positive-finite-number.mts +191 -0
- package/src/number/branded-types/non-positive-finite-number.test.mts +286 -0
- package/src/number/branded-types/non-positive-int.mts +251 -0
- package/src/number/branded-types/non-positive-int.test.mts +197 -0
- package/src/number/branded-types/non-positive-safe-int.mts +147 -0
- package/src/number/branded-types/non-positive-safe-int.test.mts +223 -0
- package/src/number/branded-types/non-zero-finite-number.mts +14 -22
- package/src/number/branded-types/non-zero-finite-number.test.mts +0 -12
- package/src/number/branded-types/non-zero-int.mts +10 -32
- package/src/number/branded-types/non-zero-int.test.mts +0 -20
- package/src/number/branded-types/non-zero-int16.mts +8 -32
- package/src/number/branded-types/non-zero-int16.test.mts +0 -30
- package/src/number/branded-types/non-zero-int32.mts +8 -32
- package/src/number/branded-types/non-zero-int32.test.mts +0 -30
- package/src/number/branded-types/non-zero-safe-int.mts +10 -37
- package/src/number/branded-types/non-zero-safe-int.test.mts +0 -32
- package/src/number/branded-types/non-zero-uint16.mts +8 -22
- package/src/number/branded-types/non-zero-uint16.test.mts +0 -16
- package/src/number/branded-types/non-zero-uint32.mts +8 -22
- package/src/number/branded-types/non-zero-uint32.test.mts +0 -16
- package/src/number/branded-types/positive-safe-int.mts +1 -1
- package/src/number/branded-types/safe-int.mts +2 -2
- package/src/number/branded-types/safe-uint.mts +1 -1
- package/src/number/index.mts +1 -0
- package/src/number/num-arithmetic-types.mts +265 -0
- package/src/number/num-arithmetic-types.test.mts +130 -0
- package/src/number/num-arithmetic.test.mts +102 -0
- package/src/number/num.mts +99 -18
- package/src/number/num.test.mts +2 -2
- package/src/number/refined-number-utils.mts +19 -9
- package/src/object/object.mts +2 -2
- package/src/others/fast-deep-equal.mts +0 -2
- package/src/others/map-nullable.test.mts +4 -3
- package/src/others/unknown-to-string.mts +2 -2
|
@@ -12,9 +12,9 @@ import { type UnwrapErr, type UnwrapOk } from './types.mjs';
|
|
|
12
12
|
*
|
|
13
13
|
* ```ts
|
|
14
14
|
* const parseNumber = (input: string): Result<number, string> => {
|
|
15
|
-
* const num =
|
|
15
|
+
* const num = Num.safeParseInt(input);
|
|
16
16
|
*
|
|
17
|
-
* return
|
|
17
|
+
* return Result.mapErr(num, () => 'not a number');
|
|
18
18
|
* };
|
|
19
19
|
*
|
|
20
20
|
* const parsed = Result.flatMap(Result.ok('42'), parseNumber);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { expectType } from '../expect-type.mjs';
|
|
2
|
+
import { Num } from '../number/index.mjs';
|
|
2
3
|
import { type Err, type Ok } from '../types.mjs';
|
|
3
4
|
import { Optional } from './optional/index.mjs';
|
|
4
5
|
import { pipe } from './pipe.mjs';
|
|
@@ -467,7 +468,7 @@ describe('Result test', () => {
|
|
|
467
468
|
|
|
468
469
|
test('should support chaining multiple flatMaps', () => {
|
|
469
470
|
const parseNumber = (s: string): Result<number, string> => {
|
|
470
|
-
const n =
|
|
471
|
+
const n = Result.unwrapOkOr(Num.safeParseFloat(s), Number.NaN);
|
|
471
472
|
|
|
472
473
|
return Number.isNaN(n) ? Result.err('Not a number') : Result.ok(n);
|
|
473
474
|
};
|
|
@@ -518,7 +519,7 @@ describe('Result test', () => {
|
|
|
518
519
|
|
|
519
520
|
test('should work with pipe when curried', () => {
|
|
520
521
|
const parseNumber = (s: string): Result<number, string> => {
|
|
521
|
-
const n =
|
|
522
|
+
const n = Result.unwrapOkOr(Num.safeParseFloat(s), Number.NaN);
|
|
522
523
|
|
|
523
524
|
return Number.isNaN(n) ? Result.err('Not a number') : Result.ok(n);
|
|
524
525
|
};
|
|
@@ -15,9 +15,11 @@ import { type UnwrapErr, type UnwrapOk, type UnwrapWarn } from './types.mjs';
|
|
|
15
15
|
*
|
|
16
16
|
* ```ts
|
|
17
17
|
* const parse = (value: string): TernaryResult<number, string, string> =>
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
18
|
+
* pipe(Num.safeParseFloat(value)).map((result) =>
|
|
19
|
+
* Result.isErr(result)
|
|
20
|
+
* ? TernaryResult.err('NaN')
|
|
21
|
+
* : TernaryResult.ok(result.value),
|
|
22
|
+
* ).value;
|
|
21
23
|
*
|
|
22
24
|
* const doubled = TernaryResult.flatMap(TernaryResult.ok('3'), (text) =>
|
|
23
25
|
* TernaryResult.map(parse(text), (num) => num * 2),
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { expectType } from '../expect-type.mjs';
|
|
2
|
+
import { Num } from '../number/index.mjs';
|
|
2
3
|
import { Optional } from './optional/index.mjs';
|
|
4
|
+
import { pipe } from './pipe.mjs';
|
|
5
|
+
import { Result } from './result/index.mjs';
|
|
3
6
|
import { TernaryResult } from './ternary-result/index.mjs';
|
|
4
7
|
|
|
5
8
|
describe('TernaryResult test', () => {
|
|
@@ -69,9 +72,11 @@ describe('TernaryResult test', () => {
|
|
|
69
72
|
|
|
70
73
|
test('flatMap propagates Warn and Err while keeping warnings', () => {
|
|
71
74
|
const parse = (value: string): TernaryResult<number, string, never> =>
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
+
pipe(Num.safeParseFloat(value)).map((result) =>
|
|
76
|
+
Result.isErr(result)
|
|
77
|
+
? TernaryResult.err('NaN')
|
|
78
|
+
: TernaryResult.ok(result.value),
|
|
79
|
+
).value;
|
|
75
80
|
|
|
76
81
|
const warn = TernaryResult.warn('3', 'slow');
|
|
77
82
|
|
package/src/guard/has-key.mts
CHANGED
|
@@ -47,9 +47,7 @@ export const hasKey = <
|
|
|
47
47
|
>(
|
|
48
48
|
obj: R,
|
|
49
49
|
key: K,
|
|
50
|
-
): obj is HasKeyReturnType<R, K> =>
|
|
51
|
-
// eslint-disable-next-line ts-data-forge/prefer-is-record-and-has-key
|
|
52
|
-
Object.hasOwn(obj, key);
|
|
50
|
+
): obj is HasKeyReturnType<R, K> => Object.hasOwn(obj, key);
|
|
53
51
|
|
|
54
52
|
/**
|
|
55
53
|
* @internal
|
package/src/guard/key-is-in.mts
CHANGED
package/src/json/json.mts
CHANGED
|
@@ -350,18 +350,15 @@ const keysDeepImpl = (
|
|
|
350
350
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
351
351
|
mut_keys: string[],
|
|
352
352
|
): void => {
|
|
353
|
-
for (const k of Object.
|
|
353
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
354
354
|
mut_keys.push(k);
|
|
355
355
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
if (isRecord(o)) {
|
|
359
|
-
keysDeepImpl(o, mut_keys);
|
|
356
|
+
if (isRecord(v)) {
|
|
357
|
+
keysDeepImpl(v, mut_keys);
|
|
360
358
|
}
|
|
361
359
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
for (const li of o) {
|
|
360
|
+
if (Array.isArray(v)) {
|
|
361
|
+
for (const li of v) {
|
|
365
362
|
if (isRecord(li)) {
|
|
366
363
|
keysDeepImpl(li, mut_keys);
|
|
367
364
|
}
|
package/src/json/json.test.mts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Arr } from '../array/index.mjs';
|
|
2
2
|
import { Result } from '../functional/index.mjs';
|
|
3
3
|
import { hasKey, isRecord, isString } from '../guard/index.mjs';
|
|
4
|
+
import { Num } from '../number/index.mjs';
|
|
4
5
|
import { Json } from './json.mjs';
|
|
5
6
|
|
|
6
7
|
describe('parse', () => {
|
|
@@ -154,7 +155,7 @@ describe('parse', () => {
|
|
|
154
155
|
test('should handle reviver returning different types', () => {
|
|
155
156
|
const transformReviver = (key: string, value: unknown): unknown => {
|
|
156
157
|
if (key === 'number' && typeof value === 'string') {
|
|
157
|
-
return
|
|
158
|
+
return Result.unwrapOkOr(Num.safeParseInt(value), Number.NaN);
|
|
158
159
|
}
|
|
159
160
|
|
|
160
161
|
return value;
|
|
@@ -465,7 +466,6 @@ describe('stringifySelected', () => {
|
|
|
465
466
|
|
|
466
467
|
// Note: stringifySelected works with JSON.stringify's replacer parameter
|
|
467
468
|
// which may not work as expected with arrays
|
|
468
|
-
// eslint-disable-next-line ts-data-forge/prefer-arr-is-array
|
|
469
469
|
assert.isTrue(Array.isArray(parsed));
|
|
470
470
|
|
|
471
471
|
expect(parsed).toHaveLength(3);
|
|
@@ -2,9 +2,15 @@ export * from './finite-number.mjs';
|
|
|
2
2
|
export * from './int.mjs';
|
|
3
3
|
export * from './int16.mjs';
|
|
4
4
|
export * from './int32.mjs';
|
|
5
|
+
export * from './negative-finite-number.mjs';
|
|
6
|
+
export * from './negative-int.mjs';
|
|
7
|
+
export * from './negative-safe-int.mjs';
|
|
5
8
|
export * from './non-negative-finite-number.mjs';
|
|
6
9
|
export * from './non-negative-int16.mjs';
|
|
7
10
|
export * from './non-negative-int32.mjs';
|
|
11
|
+
export * from './non-positive-finite-number.mjs';
|
|
12
|
+
export * from './non-positive-int.mjs';
|
|
13
|
+
export * from './non-positive-safe-int.mjs';
|
|
8
14
|
export * from './non-zero-finite-number.mjs';
|
|
9
15
|
export * from './non-zero-int.mjs';
|
|
10
16
|
export * from './non-zero-int16.mjs';
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { type NegativeFiniteNumber as TtfImported_NegativeFiniteNumber } from 'ts-type-forge';
|
|
2
|
+
import { TsDataForgeInternals } from '../refined-number-utils.mjs';
|
|
3
|
+
import { PositiveFiniteNumber } from './positive-finite-number.mjs';
|
|
4
|
+
|
|
5
|
+
export type NegativeFiniteNumber = TtfImported_NegativeFiniteNumber;
|
|
6
|
+
|
|
7
|
+
type ElementType = NegativeFiniteNumber;
|
|
8
|
+
|
|
9
|
+
const typeNameInMessage = 'a negative finite number';
|
|
10
|
+
|
|
11
|
+
const {
|
|
12
|
+
MAX_VALUE,
|
|
13
|
+
add,
|
|
14
|
+
castType,
|
|
15
|
+
clamp,
|
|
16
|
+
is,
|
|
17
|
+
max: max_,
|
|
18
|
+
min: min_,
|
|
19
|
+
pow,
|
|
20
|
+
random,
|
|
21
|
+
sub,
|
|
22
|
+
} = TsDataForgeInternals.RefinedNumberUtils.operatorsForFloat<
|
|
23
|
+
ElementType,
|
|
24
|
+
number,
|
|
25
|
+
number
|
|
26
|
+
>({
|
|
27
|
+
nonZero: true,
|
|
28
|
+
MIN_VALUE: -Number.MAX_VALUE,
|
|
29
|
+
MAX_VALUE: -Number.MIN_VALUE,
|
|
30
|
+
typeNameInMessage,
|
|
31
|
+
} as const);
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Returns the absolute value of a negative finite number.
|
|
35
|
+
*
|
|
36
|
+
* The absolute value of a negative finite number is always a positive finite
|
|
37
|
+
* number, so the result is typed as a {@link PositiveFiniteNumber}.
|
|
38
|
+
*
|
|
39
|
+
* @param x - The negative finite number.
|
|
40
|
+
* @returns `|x|` as a PositiveFiniteNumber.
|
|
41
|
+
*/
|
|
42
|
+
const abs = (x: ElementType): PositiveFiniteNumber =>
|
|
43
|
+
PositiveFiniteNumber.clamp(Math.abs(x));
|
|
44
|
+
|
|
45
|
+
const floor = (
|
|
46
|
+
x: ElementType,
|
|
47
|
+
): TsDataForgeInternals.RefinedNumberUtils.ToInt<ElementType> =>
|
|
48
|
+
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
|
|
49
|
+
Math.floor(x) as TsDataForgeInternals.RefinedNumberUtils.ToInt<ElementType>;
|
|
50
|
+
|
|
51
|
+
const ceil = (
|
|
52
|
+
x: ElementType,
|
|
53
|
+
): TsDataForgeInternals.RefinedNumberUtils.RemoveNonZeroBrandKey<
|
|
54
|
+
TsDataForgeInternals.RefinedNumberUtils.ToInt<ElementType>
|
|
55
|
+
> =>
|
|
56
|
+
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
|
|
57
|
+
Math.ceil(x) as TsDataForgeInternals.RefinedNumberUtils.RemoveNonZeroBrandKey<
|
|
58
|
+
TsDataForgeInternals.RefinedNumberUtils.ToInt<ElementType>
|
|
59
|
+
>;
|
|
60
|
+
|
|
61
|
+
const round = (
|
|
62
|
+
x: ElementType,
|
|
63
|
+
): TsDataForgeInternals.RefinedNumberUtils.RemoveNonZeroBrandKey<
|
|
64
|
+
TsDataForgeInternals.RefinedNumberUtils.ToInt<ElementType>
|
|
65
|
+
> =>
|
|
66
|
+
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
|
|
67
|
+
Math.round(
|
|
68
|
+
x,
|
|
69
|
+
) as TsDataForgeInternals.RefinedNumberUtils.RemoveNonZeroBrandKey<
|
|
70
|
+
TsDataForgeInternals.RefinedNumberUtils.ToInt<ElementType>
|
|
71
|
+
>;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Checks if a number is a NegativeFiniteNumber (a finite number `< 0`).
|
|
75
|
+
*
|
|
76
|
+
* @param value The value to check.
|
|
77
|
+
* @returns `true` if the value is a NegativeFiniteNumber, `false` otherwise.
|
|
78
|
+
*/
|
|
79
|
+
export const isNegativeFiniteNumber = is;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Casts a number to a NegativeFiniteNumber type.
|
|
83
|
+
*
|
|
84
|
+
* @param value The value to cast.
|
|
85
|
+
* @returns The value as a NegativeFiniteNumber type.
|
|
86
|
+
* @throws {TypeError} If the value is not a negative finite number.
|
|
87
|
+
*/
|
|
88
|
+
export const asNegativeFiniteNumber = castType;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Namespace providing type-safe arithmetic operations for negative finite
|
|
92
|
+
* numbers.
|
|
93
|
+
*
|
|
94
|
+
* All operations keep results finite (excluding NaN and Infinity). Operations
|
|
95
|
+
* that stay within the negative finite numbers clamp their results to the valid
|
|
96
|
+
* range, while operations whose result leaves the set (`mul`, `div`, `abs`) are
|
|
97
|
+
* typed to reflect the actual sign of the result.
|
|
98
|
+
*/
|
|
99
|
+
export const NegativeFiniteNumber = {
|
|
100
|
+
/**
|
|
101
|
+
* Type guard to check if a value is a NegativeFiniteNumber.
|
|
102
|
+
*
|
|
103
|
+
* @param value The value to check.
|
|
104
|
+
* @returns `true` if the value is a negative finite number, `false`
|
|
105
|
+
* otherwise.
|
|
106
|
+
*/
|
|
107
|
+
is,
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* The maximum value for a negative finite number.
|
|
111
|
+
*
|
|
112
|
+
* @readonly
|
|
113
|
+
*/
|
|
114
|
+
MAX_VALUE,
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Returns the absolute value of a negative finite number.
|
|
118
|
+
*
|
|
119
|
+
* @param a The negative finite number.
|
|
120
|
+
* @returns The absolute value as a PositiveFiniteNumber.
|
|
121
|
+
*/
|
|
122
|
+
abs,
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Returns the smaller of two NegativeFiniteNumber values.
|
|
126
|
+
*
|
|
127
|
+
* @param a The first NegativeFiniteNumber.
|
|
128
|
+
* @param b The second NegativeFiniteNumber.
|
|
129
|
+
* @returns The minimum value as a NegativeFiniteNumber.
|
|
130
|
+
*/
|
|
131
|
+
min: min_,
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Returns the larger of two NegativeFiniteNumber values.
|
|
135
|
+
*
|
|
136
|
+
* @param a The first NegativeFiniteNumber.
|
|
137
|
+
* @param b The second NegativeFiniteNumber.
|
|
138
|
+
* @returns The maximum value as a NegativeFiniteNumber.
|
|
139
|
+
*/
|
|
140
|
+
max: max_,
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Clamps a number to the negative finite range.
|
|
144
|
+
*
|
|
145
|
+
* @param value The number to clamp.
|
|
146
|
+
* @returns The value clamped to `(-∞, 0)` as a NegativeFiniteNumber.
|
|
147
|
+
*/
|
|
148
|
+
clamp,
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Rounds down a NegativeFiniteNumber to the nearest integer.
|
|
152
|
+
*
|
|
153
|
+
* @param x The NegativeFiniteNumber to round down.
|
|
154
|
+
* @returns The floor value as a NegativeInt (always `<= -1`).
|
|
155
|
+
*/
|
|
156
|
+
floor,
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Rounds up a NegativeFiniteNumber to the nearest integer.
|
|
160
|
+
*
|
|
161
|
+
* @param x The NegativeFiniteNumber to round up.
|
|
162
|
+
* @returns The ceiling value as a NonPositiveInt (can be 0).
|
|
163
|
+
*/
|
|
164
|
+
ceil,
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Rounds a NegativeFiniteNumber to the nearest integer.
|
|
168
|
+
*
|
|
169
|
+
* @param x The NegativeFiniteNumber to round.
|
|
170
|
+
* @returns The rounded value as a NonPositiveInt (can be 0 if x > -0.5).
|
|
171
|
+
*/
|
|
172
|
+
round,
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Generates a random NegativeFiniteNumber value.
|
|
176
|
+
*
|
|
177
|
+
* @returns A random negative finite number.
|
|
178
|
+
*/
|
|
179
|
+
random,
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Raises a NegativeFiniteNumber to the power of another NegativeFiniteNumber.
|
|
183
|
+
*
|
|
184
|
+
* @param a The base NegativeFiniteNumber.
|
|
185
|
+
* @param b The exponent NegativeFiniteNumber.
|
|
186
|
+
* @returns `a ** b` clamped to `(-∞, 0)` as a NegativeFiniteNumber.
|
|
187
|
+
*/
|
|
188
|
+
pow,
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Adds two NegativeFiniteNumber values.
|
|
192
|
+
*
|
|
193
|
+
* @param a The first NegativeFiniteNumber.
|
|
194
|
+
* @param b The second NegativeFiniteNumber.
|
|
195
|
+
* @returns `a + b` as a NegativeFiniteNumber.
|
|
196
|
+
*/
|
|
197
|
+
add,
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Subtracts one NegativeFiniteNumber from another.
|
|
201
|
+
*
|
|
202
|
+
* The mathematical result can be positive, so it is clamped to the negative
|
|
203
|
+
* finite range (maximum `-Number.MIN_VALUE`).
|
|
204
|
+
*
|
|
205
|
+
* @param a The minuend NegativeFiniteNumber.
|
|
206
|
+
* @param b The subtrahend NegativeFiniteNumber.
|
|
207
|
+
* @returns `a - b` clamped to `(-∞, 0)` as a NegativeFiniteNumber.
|
|
208
|
+
*/
|
|
209
|
+
sub,
|
|
210
|
+
} as const;
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type NegativeInt,
|
|
3
|
+
type NonPositiveInt,
|
|
4
|
+
type PositiveFiniteNumber,
|
|
5
|
+
} from 'ts-type-forge';
|
|
6
|
+
import { expectType } from '../../expect-type.mjs';
|
|
7
|
+
import { range } from '../../iterator/index.mjs';
|
|
8
|
+
import {
|
|
9
|
+
asNegativeFiniteNumber,
|
|
10
|
+
isNegativeFiniteNumber,
|
|
11
|
+
NegativeFiniteNumber,
|
|
12
|
+
} from './negative-finite-number.mjs';
|
|
13
|
+
|
|
14
|
+
describe('NegativeFiniteNumber test', () => {
|
|
15
|
+
describe(asNegativeFiniteNumber, () => {
|
|
16
|
+
test('accepts valid negative finite numbers', () => {
|
|
17
|
+
expect(() => asNegativeFiniteNumber(-1)).not.toThrow();
|
|
18
|
+
|
|
19
|
+
expect(() => asNegativeFiniteNumber(-1.5)).not.toThrow();
|
|
20
|
+
|
|
21
|
+
expect(() => asNegativeFiniteNumber(-1e308)).not.toThrow();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('rejects zero and positive numbers', () => {
|
|
25
|
+
expect(() => asNegativeFiniteNumber(0)).toThrow(TypeError);
|
|
26
|
+
|
|
27
|
+
expect(() => asNegativeFiniteNumber(1.5)).toThrow(TypeError);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test('rejects non-finite values', () => {
|
|
31
|
+
expect(() => asNegativeFiniteNumber(Number.NaN)).toThrow(TypeError);
|
|
32
|
+
|
|
33
|
+
expect(() => asNegativeFiniteNumber(Number.NEGATIVE_INFINITY)).toThrow(
|
|
34
|
+
TypeError,
|
|
35
|
+
);
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
describe(isNegativeFiniteNumber, () => {
|
|
40
|
+
test('correctly identifies negative finite numbers', () => {
|
|
41
|
+
assert.isTrue(isNegativeFiniteNumber(-1));
|
|
42
|
+
|
|
43
|
+
assert.isTrue(isNegativeFiniteNumber(-1.5));
|
|
44
|
+
|
|
45
|
+
assert.isFalse(isNegativeFiniteNumber(0));
|
|
46
|
+
|
|
47
|
+
assert.isFalse(isNegativeFiniteNumber(1));
|
|
48
|
+
|
|
49
|
+
assert.isFalse(isNegativeFiniteNumber(Number.NEGATIVE_INFINITY));
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
describe('NegativeFiniteNumber.is', () => {
|
|
54
|
+
test('works as a type guard', () => {
|
|
55
|
+
const value: number = -42.5;
|
|
56
|
+
|
|
57
|
+
if (NegativeFiniteNumber.is(value)) {
|
|
58
|
+
expectType<typeof value, typeof value & NegativeFiniteNumber>('=');
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
describe('NegativeFiniteNumber.abs', () => {
|
|
64
|
+
test('returns the absolute value as a positive finite number', () => {
|
|
65
|
+
expect(
|
|
66
|
+
NegativeFiniteNumber.abs(asNegativeFiniteNumber(-5.5)),
|
|
67
|
+
).toBeCloseTo(5.5, 5);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test('result type is PositiveFiniteNumber', () => {
|
|
71
|
+
expectType<
|
|
72
|
+
ReturnType<typeof NegativeFiniteNumber.abs>,
|
|
73
|
+
PositiveFiniteNumber
|
|
74
|
+
>('=');
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
describe('NegativeFiniteNumber.min / max', () => {
|
|
79
|
+
test('returns the expected extremum', () => {
|
|
80
|
+
expect(
|
|
81
|
+
NegativeFiniteNumber.min(
|
|
82
|
+
asNegativeFiniteNumber(-5.5),
|
|
83
|
+
asNegativeFiniteNumber(-10.5),
|
|
84
|
+
),
|
|
85
|
+
).toBeCloseTo(-10.5, 5);
|
|
86
|
+
|
|
87
|
+
expect(
|
|
88
|
+
NegativeFiniteNumber.max(
|
|
89
|
+
asNegativeFiniteNumber(-5.5),
|
|
90
|
+
asNegativeFiniteNumber(-10.5),
|
|
91
|
+
),
|
|
92
|
+
).toBeCloseTo(-5.5, 5);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
describe('NegativeFiniteNumber.clamp', () => {
|
|
97
|
+
test('clamps non-negative values into range', () => {
|
|
98
|
+
expect(NegativeFiniteNumber.clamp(-5.5)).toBeCloseTo(-5.5, 5);
|
|
99
|
+
|
|
100
|
+
expect(NegativeFiniteNumber.clamp(0)).toBeLessThan(0);
|
|
101
|
+
|
|
102
|
+
expect(NegativeFiniteNumber.clamp(5)).toBeLessThan(0);
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
describe('NegativeFiniteNumber.floor / ceil / round', () => {
|
|
107
|
+
test('rounds toward integers', () => {
|
|
108
|
+
expect(NegativeFiniteNumber.floor(asNegativeFiniteNumber(-2.3))).toBe(-3);
|
|
109
|
+
|
|
110
|
+
expect(NegativeFiniteNumber.ceil(asNegativeFiniteNumber(-2.3))).toBe(-2);
|
|
111
|
+
|
|
112
|
+
expect(
|
|
113
|
+
NegativeFiniteNumber.ceil(asNegativeFiniteNumber(-0.5)),
|
|
114
|
+
).toBeCloseTo(0);
|
|
115
|
+
|
|
116
|
+
expect(
|
|
117
|
+
NegativeFiniteNumber.round(asNegativeFiniteNumber(-0.4)),
|
|
118
|
+
).toBeCloseTo(0);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
test('floor result type is NegativeInt', () => {
|
|
122
|
+
expectType<ReturnType<typeof NegativeFiniteNumber.floor>, NegativeInt>(
|
|
123
|
+
'=',
|
|
124
|
+
);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
test('ceil/round result type is NonPositiveInt', () => {
|
|
128
|
+
expectType<ReturnType<typeof NegativeFiniteNumber.ceil>, NonPositiveInt>(
|
|
129
|
+
'=',
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
expectType<ReturnType<typeof NegativeFiniteNumber.round>, NonPositiveInt>(
|
|
133
|
+
'=',
|
|
134
|
+
);
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
describe('NegativeFiniteNumber.add / sub', () => {
|
|
139
|
+
test('adds and subtracts within range', () => {
|
|
140
|
+
expect(
|
|
141
|
+
NegativeFiniteNumber.add(
|
|
142
|
+
asNegativeFiniteNumber(-5.5),
|
|
143
|
+
asNegativeFiniteNumber(-3.5),
|
|
144
|
+
),
|
|
145
|
+
).toBeCloseTo(-9, 5);
|
|
146
|
+
|
|
147
|
+
expect(
|
|
148
|
+
NegativeFiniteNumber.sub(
|
|
149
|
+
asNegativeFiniteNumber(-10.5),
|
|
150
|
+
asNegativeFiniteNumber(-3.5),
|
|
151
|
+
),
|
|
152
|
+
).toBeCloseTo(-7, 5);
|
|
153
|
+
|
|
154
|
+
expect(
|
|
155
|
+
NegativeFiniteNumber.sub(
|
|
156
|
+
asNegativeFiniteNumber(-3.5),
|
|
157
|
+
asNegativeFiniteNumber(-10.5),
|
|
158
|
+
),
|
|
159
|
+
).toBeLessThan(0);
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
describe('NegativeFiniteNumber.random', () => {
|
|
164
|
+
test('generates values within range', () => {
|
|
165
|
+
for (const _ of range(100)) {
|
|
166
|
+
const value = NegativeFiniteNumber.random();
|
|
167
|
+
|
|
168
|
+
assert.isTrue(isNegativeFiniteNumber(value));
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
});
|