ts-data-forge 10.0.0 → 11.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 (79) hide show
  1. package/dist/array/impl/array-utils-creation.d.mts +3 -3
  2. package/dist/array/impl/array-utils-creation.d.mts.map +1 -1
  3. package/dist/array/impl/array-utils-creation.mjs.map +1 -1
  4. package/dist/array/impl/array-utils-element-access.d.mts +4 -4
  5. package/dist/array/impl/array-utils-element-access.mjs.map +1 -1
  6. package/dist/{guard/as-length-bounded-array.d.mts → array/impl/array-utils-length-bounded-array-cast.d.mts} +9 -9
  7. package/dist/array/impl/array-utils-length-bounded-array-cast.d.mts.map +1 -0
  8. package/dist/{guard/as-length-bounded-array.mjs → array/impl/array-utils-length-bounded-array-cast.mjs} +2 -2
  9. package/dist/array/impl/array-utils-length-bounded-array-cast.mjs.map +1 -0
  10. package/dist/{guard/is-length-bounded-array.d.mts → array/impl/array-utils-length-bounded-array-guard.d.mts} +13 -13
  11. package/dist/array/impl/array-utils-length-bounded-array-guard.d.mts.map +1 -0
  12. package/dist/{guard/is-length-bounded-array.mjs → array/impl/array-utils-length-bounded-array-guard.mjs} +1 -1
  13. package/dist/array/impl/array-utils-length-bounded-array-guard.mjs.map +1 -0
  14. package/dist/array/impl/array-utils-modification.d.mts +9 -9
  15. package/dist/array/impl/array-utils-modification.d.mts.map +1 -1
  16. package/dist/array/impl/array-utils-modification.mjs.map +1 -1
  17. package/dist/array/impl/array-utils-reducing-value.d.mts +9 -9
  18. package/dist/array/impl/array-utils-reducing-value.mjs.map +1 -1
  19. package/dist/array/impl/array-utils-size.d.mts +3 -3
  20. package/dist/array/impl/array-utils-size.mjs.map +1 -1
  21. package/dist/array/impl/array-utils-slicing.d.mts +9 -9
  22. package/dist/array/impl/array-utils-slicing.d.mts.map +1 -1
  23. package/dist/array/impl/array-utils-slicing.mjs.map +1 -1
  24. package/dist/array/impl/array-utils-transformation.d.mts +16 -10
  25. package/dist/array/impl/array-utils-transformation.d.mts.map +1 -1
  26. package/dist/array/impl/array-utils-transformation.mjs.map +1 -1
  27. package/dist/array/impl/index.d.mts +2 -0
  28. package/dist/array/impl/index.d.mts.map +1 -1
  29. package/dist/array/impl/index.mjs +2 -0
  30. package/dist/array/impl/index.mjs.map +1 -1
  31. package/dist/entry-point.mjs +1 -3
  32. package/dist/entry-point.mjs.map +1 -1
  33. package/dist/guard/index.d.mts +0 -3
  34. package/dist/guard/index.d.mts.map +1 -1
  35. package/dist/guard/index.mjs +0 -3
  36. package/dist/guard/index.mjs.map +1 -1
  37. package/dist/index.d.mts +1 -0
  38. package/dist/index.d.mts.map +1 -1
  39. package/dist/index.mjs +1 -3
  40. package/dist/index.mjs.map +1 -1
  41. package/dist/string/index.d.mts +2 -0
  42. package/dist/string/index.d.mts.map +1 -0
  43. package/dist/string/index.mjs +2 -0
  44. package/dist/string/index.mjs.map +1 -0
  45. package/dist/string/str.d.mts +273 -0
  46. package/dist/string/str.d.mts.map +1 -0
  47. package/dist/string/str.mjs +42 -0
  48. package/dist/string/str.mjs.map +1 -0
  49. package/package.json +30 -92
  50. package/src/array/impl/array-utils-creation.mts +2 -1
  51. package/src/array/impl/array-utils-element-access.mts +3 -3
  52. package/src/array/impl/array-utils-element-access.test.mts +3 -3
  53. package/src/{guard/as-length-bounded-array.mts → array/impl/array-utils-length-bounded-array-cast.mts} +9 -9
  54. package/src/{guard/as-length-bounded-array.test.mts → array/impl/array-utils-length-bounded-array-cast.test.mts} +2 -2
  55. package/src/{guard/is-length-bounded-array.mts → array/impl/array-utils-length-bounded-array-guard.mts} +12 -12
  56. package/src/{guard/is-length-bounded-array.test.mts → array/impl/array-utils-length-bounded-array-guard.test.mts} +2 -2
  57. package/src/array/impl/array-utils-modification.mts +9 -8
  58. package/src/array/impl/array-utils-modification.test.mts +6 -1
  59. package/src/array/impl/array-utils-reducing-value.mts +9 -9
  60. package/src/array/impl/array-utils-size.mts +2 -2
  61. package/src/array/impl/array-utils-slicing.mts +24 -13
  62. package/src/array/impl/array-utils-transformation.mts +18 -12
  63. package/src/array/impl/array-utils-transformation.test.mts +12 -12
  64. package/src/array/impl/index.mts +2 -0
  65. package/src/guard/index.mts +0 -3
  66. package/src/index.mts +1 -0
  67. package/src/string/index.mts +1 -0
  68. package/src/string/str.mts +371 -0
  69. package/src/string/str.test.mts +215 -0
  70. package/dist/guard/as-length-bounded-array.d.mts.map +0 -1
  71. package/dist/guard/as-length-bounded-array.mjs.map +0 -1
  72. package/dist/guard/is-length-bounded-array.d.mts.map +0 -1
  73. package/dist/guard/is-length-bounded-array.mjs.map +0 -1
  74. package/dist/guard/is-length-bounded-string.d.mts +0 -163
  75. package/dist/guard/is-length-bounded-string.d.mts.map +0 -1
  76. package/dist/guard/is-length-bounded-string.mjs +0 -7
  77. package/dist/guard/is-length-bounded-string.mjs.map +0 -1
  78. package/src/guard/is-length-bounded-string.mts +0 -199
  79. package/src/guard/is-length-bounded-string.test.mts +0 -170
@@ -10,7 +10,7 @@ import {
10
10
  isFixedLengthArray,
11
11
  isMaxLengthArray,
12
12
  isMinLengthArray,
13
- } from './is-length-bounded-array.mjs';
13
+ } from './array-utils-length-bounded-array-guard.mjs';
14
14
 
15
15
  /**
16
16
  * Casts an array to `FixedLengthArray<Length, E>` after checking that it has
@@ -25,12 +25,12 @@ import {
25
25
  * @example
26
26
  *
27
27
  * ```ts
28
- * const rgb = asFixedLengthArray([255, 128, 0], 3);
28
+ * const rgb = Arr.asFixedLengthArray([255, 128, 0], 3);
29
29
  *
30
30
  * const atMost5: MaxLengthArray<5, number> = rgb; // OK (3 <= 5)
31
31
  * const red: number = rgb[0]; // OK — no `undefined`
32
32
  *
33
- * // asFixedLengthArray([255, 128], 3); // throws TypeError
33
+ * // Arr.asFixedLengthArray([255, 128], 3); // throws TypeError
34
34
  * ```
35
35
  *
36
36
  * @template Xs - The input array type (tuple types are preserved).
@@ -69,12 +69,12 @@ export const asFixedLengthArray = <
69
69
  * @example
70
70
  *
71
71
  * ```ts
72
- * const history = asMinLengthArray([0, 1, 2, 3], 3);
72
+ * const history = Arr.asMinLengthArray([0, 1, 2, 3], 3);
73
73
  *
74
74
  * const nonEmpty: MinLengthArray<1, number> = history; // OK (3 >= 1)
75
75
  * const first: number = history[0]; // OK — no `undefined`
76
76
  *
77
- * // asMinLengthArray([0], 3); // throws TypeError
77
+ * // Arr.asMinLengthArray([0], 3); // throws TypeError
78
78
  * ```
79
79
  *
80
80
  * @template Xs - The input array type (tuple types are preserved).
@@ -111,11 +111,11 @@ export const asMinLengthArray = <
111
111
  * @example
112
112
  *
113
113
  * ```ts
114
- * const tags = asMaxLengthArray(['a', 'b', 'c'], 8);
114
+ * const tags = Arr.asMaxLengthArray(['a', 'b', 'c'], 8);
115
115
  *
116
116
  * const relaxed: MaxLengthArray<16, string> = tags; // OK (8 <= 16)
117
117
  *
118
- * // asMaxLengthArray(['a', 'b', 'c'], 2); // throws TypeError
118
+ * // Arr.asMaxLengthArray(['a', 'b', 'c'], 2); // throws TypeError
119
119
  * ```
120
120
  *
121
121
  * @template Xs - The input array type (tuple types are preserved).
@@ -154,11 +154,11 @@ export const asMaxLengthArray = <
154
154
  * @example
155
155
  *
156
156
  * ```ts
157
- * const selection = asBoundedLengthArray([1, 2, 3], 1, 5);
157
+ * const selection = Arr.asBoundedLengthArray([1, 2, 3], 1, 5);
158
158
  *
159
159
  * const relaxed: BoundedLengthArray<0, 100, number> = selection; // OK
160
160
  *
161
- * // asBoundedLengthArray([], 1, 5); // throws TypeError
161
+ * // Arr.asBoundedLengthArray([], 1, 5); // throws TypeError
162
162
  * ```
163
163
  *
164
164
  * @template Xs - The input array type (tuple types are preserved).
@@ -4,13 +4,13 @@ import {
4
4
  type MaxLengthArray,
5
5
  type MinLengthArray,
6
6
  } from 'ts-type-forge';
7
- import { expectType } from '../expect-type.mjs';
7
+ import { expectType } from '../../expect-type.mjs';
8
8
  import {
9
9
  asBoundedLengthArray,
10
10
  asFixedLengthArray,
11
11
  asMaxLengthArray,
12
12
  asMinLengthArray,
13
- } from './as-length-bounded-array.mjs';
13
+ } from './array-utils-length-bounded-array-cast.mjs';
14
14
 
15
15
  describe(asFixedLengthArray, () => {
16
16
  test('should return the input when the length matches exactly', () => {
@@ -25,11 +25,11 @@ import {
25
25
  * ```ts
26
26
  * const input: readonly number[] = [0, 1, 2, 3];
27
27
  *
28
- * assert.isTrue(isMinLengthArray(input, 3));
28
+ * assert.isTrue(Arr.isMinLengthArray(input, 3));
29
29
  *
30
- * assert.isFalse(isMinLengthArray([0], 3));
30
+ * assert.isFalse(Arr.isMinLengthArray([0], 3));
31
31
  *
32
- * if (isMinLengthArray(input, 3)) {
32
+ * if (Arr.isMinLengthArray(input, 3)) {
33
33
  * const history: MinLengthArray<3, number> = input;
34
34
  *
35
35
  * const nonEmpty: MinLengthArray<1, number> = input; // OK (3 >= 1)
@@ -70,11 +70,11 @@ export const isMinLengthArray = <
70
70
  * ```ts
71
71
  * const input: readonly string[] = ['a', 'b', 'c'];
72
72
  *
73
- * assert.isTrue(isMaxLengthArray(input, 8));
73
+ * assert.isTrue(Arr.isMaxLengthArray(input, 8));
74
74
  *
75
- * assert.isFalse(isMaxLengthArray(input, 2));
75
+ * assert.isFalse(Arr.isMaxLengthArray(input, 2));
76
76
  *
77
- * if (isMaxLengthArray(input, 8)) {
77
+ * if (Arr.isMaxLengthArray(input, 8)) {
78
78
  * const tags: MaxLengthArray<8, string> = input;
79
79
  *
80
80
  * const relaxed: MaxLengthArray<16, string> = input; // OK (8 <= 16)
@@ -116,11 +116,11 @@ export const isMaxLengthArray = <
116
116
  * ```ts
117
117
  * const input: readonly number[] = [1, 2, 3];
118
118
  *
119
- * assert.isTrue(isBoundedLengthArray(input, 1, 5));
119
+ * assert.isTrue(Arr.isBoundedLengthArray(input, 1, 5));
120
120
  *
121
- * assert.isFalse(isBoundedLengthArray([], 1, 5));
121
+ * assert.isFalse(Arr.isBoundedLengthArray([], 1, 5));
122
122
  *
123
- * if (isBoundedLengthArray(input, 1, 5)) {
123
+ * if (Arr.isBoundedLengthArray(input, 1, 5)) {
124
124
  * const selection: BoundedLengthArray<1, 5, number> = input;
125
125
  *
126
126
  * const relaxed: BoundedLengthArray<0, 100, number> = input; // OK ([1, 5] ⊆ [0, 100])
@@ -168,11 +168,11 @@ export const isBoundedLengthArray = <
168
168
  * ```ts
169
169
  * const input: readonly number[] = [255, 128, 0];
170
170
  *
171
- * assert.isTrue(isFixedLengthArray(input, 3));
171
+ * assert.isTrue(Arr.isFixedLengthArray(input, 3));
172
172
  *
173
- * assert.isFalse(isFixedLengthArray(input, 4));
173
+ * assert.isFalse(Arr.isFixedLengthArray(input, 4));
174
174
  *
175
- * if (isFixedLengthArray(input, 3)) {
175
+ * if (Arr.isFixedLengthArray(input, 3)) {
176
176
  * const rgb: FixedLengthArray<3, number> = input;
177
177
  *
178
178
  * const atMost5: MaxLengthArray<5, number> = input; // OK (3 <= 5)
@@ -4,13 +4,13 @@ import {
4
4
  type MaxLengthArray,
5
5
  type MinLengthArray,
6
6
  } from 'ts-type-forge';
7
- import { expectType } from '../expect-type.mjs';
7
+ import { expectType } from '../../expect-type.mjs';
8
8
  import {
9
9
  isBoundedLengthArray,
10
10
  isFixedLengthArray,
11
11
  isMaxLengthArray,
12
12
  isMinLengthArray,
13
- } from './is-length-bounded-array.mjs';
13
+ } from './array-utils-length-bounded-array-guard.mjs';
14
14
 
15
15
  describe(isMinLengthArray, () => {
16
16
  test('should return true when the array is long enough', () => {
@@ -3,6 +3,7 @@ import {
3
3
  type Increment,
4
4
  type IsFixedLengthList,
5
5
  type NonEmptyArray,
6
+ type NonEmptyTuple,
6
7
  } from 'ts-type-forge';
7
8
  import { asPositiveUint32 } from '../../number/index.mjs';
8
9
  import { castMutable } from '../../others/index.mjs';
@@ -32,7 +33,7 @@ export function set<const Ar extends readonly unknown[], const V = Ar[number]>(
32
33
  newValue: V,
33
34
  ): IsFixedLengthList<Ar> extends true
34
35
  ? Readonly<{ [K in keyof Ar]: Ar[K] | V }>
35
- : Ar extends NonEmptyArray<unknown>
36
+ : Ar extends NonEmptyTuple<unknown>
36
37
  ? NonEmptyArray<Ar[number] | V>
37
38
  : readonly (Ar[number] | V)[];
38
39
 
@@ -44,7 +45,7 @@ export function set<const V>(
44
45
  array: Ar,
45
46
  ) => IsFixedLengthList<Ar> extends true
46
47
  ? Readonly<{ [K in keyof Ar]: Ar[K] | V }>
47
- : Ar extends NonEmptyArray<unknown>
48
+ : Ar extends NonEmptyTuple<unknown>
48
49
  ? NonEmptyArray<Ar[number] | V>
49
50
  : readonly (Ar[number] | V)[];
50
51
 
@@ -97,7 +98,7 @@ export function toUpdated<
97
98
  updater: (prev: Ar[number]) => V,
98
99
  ): IsFixedLengthList<Ar> extends true
99
100
  ? Readonly<{ [K in keyof Ar]: Ar[K] | V }>
100
- : Ar extends NonEmptyArray<unknown>
101
+ : Ar extends NonEmptyTuple<unknown>
101
102
  ? NonEmptyArray<Ar[number] | V>
102
103
  : readonly (Ar[number] | V)[];
103
104
 
@@ -109,7 +110,7 @@ export function toUpdated<E, const V = E>(
109
110
  array: Ar,
110
111
  ) => IsFixedLengthList<Ar> extends true
111
112
  ? Readonly<{ [K in keyof Ar]: Ar[K] | V }>
112
- : Ar extends NonEmptyArray<unknown>
113
+ : Ar extends NonEmptyTuple<unknown>
113
114
  ? NonEmptyArray<Ar[number] | V>
114
115
  : readonly (Ar[number] | V)[];
115
116
 
@@ -368,7 +369,7 @@ export function toFilled<const Ar extends readonly unknown[], const V>(
368
369
  value: V,
369
370
  ): IsFixedLengthList<Ar> extends true
370
371
  ? FixedLengthTuple<Ar['length'], V>
371
- : Ar extends NonEmptyArray<unknown>
372
+ : Ar extends NonEmptyTuple<unknown>
372
373
  ? NonEmptyArray<V>
373
374
  : readonly V[];
374
375
 
@@ -379,7 +380,7 @@ export function toFilled<const V>(
379
380
  array: Ar,
380
381
  ) => IsFixedLengthList<Ar> extends true
381
382
  ? FixedLengthTuple<Ar['length'], V>
382
- : Ar extends NonEmptyArray<unknown>
383
+ : Ar extends NonEmptyTuple<unknown>
383
384
  ? NonEmptyArray<V>
384
385
  : readonly V[];
385
386
 
@@ -427,7 +428,7 @@ export function toRangeFilled<const Ar extends readonly unknown[], const V>(
427
428
  ],
428
429
  ): IsFixedLengthList<Ar> extends true
429
430
  ? FixedLengthTuple<Ar['length'], V | Ar[number]>
430
- : Ar extends NonEmptyArray<unknown>
431
+ : Ar extends NonEmptyTuple<unknown>
431
432
  ? NonEmptyArray<V | Ar[number]>
432
433
  : readonly (V | Ar[number])[];
433
434
 
@@ -442,7 +443,7 @@ export function toRangeFilled<const V>(
442
443
  array: Ar,
443
444
  ) => IsFixedLengthList<Ar> extends true
444
445
  ? FixedLengthTuple<Ar['length'], V | Ar[number]>
445
- : Ar extends NonEmptyArray<unknown>
446
+ : Ar extends NonEmptyTuple<unknown>
446
447
  ? NonEmptyArray<V | Ar[number]>
447
448
  : readonly (V | Ar[number])[];
448
449
 
@@ -61,7 +61,12 @@ describe('Arr modifications', () => {
61
61
 
62
62
  expectType<typeof result, NonEmptyArray<string | 5>>('=');
63
63
 
64
- assert.deepStrictEqual(result, ['a', 'b', 'c', 5]);
64
+ assert.deepStrictEqual<readonly (5 | string)[]>(result, [
65
+ 'a',
66
+ 'b',
67
+ 'c',
68
+ 5,
69
+ ]);
65
70
  });
66
71
 
67
72
  test('should work with curried version', () => {
@@ -1,5 +1,5 @@
1
1
  import { isError } from '@sindresorhus/is';
2
- import { type Int, type NonEmptyArray, type Uint } from 'ts-type-forge';
2
+ import { type Int, type NonEmptyTuple, type Uint } from 'ts-type-forge';
3
3
  import { IMap } from '../../collections/index.mjs';
4
4
  import { Optional, Result } from '../../functional/index.mjs';
5
5
  import { isString, isUndefined } from '../../guard/index.mjs';
@@ -40,12 +40,12 @@ export function min<const Ar extends readonly number[]>(
40
40
  array: Ar,
41
41
  // If the array elements are numbers, comparator is optional.
42
42
  comparator?: (x: Ar[number], y: Ar[number]) => number,
43
- ): Ar extends NonEmptyArray<unknown> ? Some<Ar[number]> : Optional<Ar[number]>;
43
+ ): Ar extends NonEmptyTuple<unknown> ? Some<Ar[number]> : Optional<Ar[number]>;
44
44
 
45
45
  export function min<const Ar extends readonly unknown[]>(
46
46
  array: Ar,
47
47
  comparator: (x: Ar[number], y: Ar[number]) => number,
48
- ): Ar extends NonEmptyArray<unknown> ? Some<Ar[number]> : Optional<Ar[number]>;
48
+ ): Ar extends NonEmptyTuple<unknown> ? Some<Ar[number]> : Optional<Ar[number]>;
49
49
 
50
50
  export function min<E extends number>(
51
51
  array: readonly E[],
@@ -86,12 +86,12 @@ export function max<const Ar extends readonly number[]>(
86
86
  array: Ar,
87
87
  // If the array elements are numbers, comparator is optional.
88
88
  comparator?: (x: Ar[number], y: Ar[number]) => number,
89
- ): Ar extends NonEmptyArray<unknown> ? Some<Ar[number]> : Optional<Ar[number]>;
89
+ ): Ar extends NonEmptyTuple<unknown> ? Some<Ar[number]> : Optional<Ar[number]>;
90
90
 
91
91
  export function max<const Ar extends readonly unknown[]>(
92
92
  array: Ar,
93
93
  comparator: (x: Ar[number], y: Ar[number]) => number,
94
- ): Ar extends NonEmptyArray<unknown> ? Some<Ar[number]> : Optional<Ar[number]>;
94
+ ): Ar extends NonEmptyTuple<unknown> ? Some<Ar[number]> : Optional<Ar[number]>;
95
95
 
96
96
  export function max<E extends number>(
97
97
  array: readonly E[],
@@ -132,13 +132,13 @@ export function minBy<const Ar extends readonly unknown[]>(
132
132
  array: Ar,
133
133
  // If the array elements are mapped to numbers, comparator is optional.
134
134
  comparatorValueMapper: (value: Ar[number]) => number,
135
- ): Ar extends NonEmptyArray<unknown> ? Some<Ar[number]> : Optional<Ar[number]>;
135
+ ): Ar extends NonEmptyTuple<unknown> ? Some<Ar[number]> : Optional<Ar[number]>;
136
136
 
137
137
  export function minBy<const Ar extends readonly unknown[], V>(
138
138
  array: Ar,
139
139
  comparatorValueMapper: (value: Ar[number]) => V,
140
140
  comparator: (x: V, y: V) => number,
141
- ): Ar extends NonEmptyArray<unknown> ? Some<Ar[number]> : Optional<Ar[number]>;
141
+ ): Ar extends NonEmptyTuple<unknown> ? Some<Ar[number]> : Optional<Ar[number]>;
142
142
 
143
143
  export function minBy<E, V>(
144
144
  array: readonly E[],
@@ -184,13 +184,13 @@ export function maxBy<const Ar extends readonly unknown[]>(
184
184
  array: Ar,
185
185
  // If the array elements are mapped to numbers, comparator is optional.
186
186
  comparatorValueMapper: (value: Ar[number]) => number,
187
- ): Ar extends NonEmptyArray<unknown> ? Some<Ar[number]> : Optional<Ar[number]>;
187
+ ): Ar extends NonEmptyTuple<unknown> ? Some<Ar[number]> : Optional<Ar[number]>;
188
188
 
189
189
  export function maxBy<const Ar extends readonly unknown[], V>(
190
190
  array: Ar,
191
191
  comparatorValueMapper: (value: Ar[number]) => V,
192
192
  comparator: (x: V, y: V) => number,
193
- ): Ar extends NonEmptyArray<unknown> ? Some<Ar[number]> : Optional<Ar[number]>;
193
+ ): Ar extends NonEmptyTuple<unknown> ? Some<Ar[number]> : Optional<Ar[number]>;
194
194
 
195
195
  export function maxBy<E, V>(
196
196
  array: readonly E[],
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  type IntersectBrand,
3
- type NonEmptyArray,
3
+ type NonEmptyTuple,
4
4
  type PositiveNumber,
5
5
  } from 'ts-type-forge';
6
6
  /**
@@ -26,7 +26,7 @@ import { type SizeType } from '../../types.mjs';
26
26
 
27
27
  export const size = <const Ar extends readonly unknown[]>(
28
28
  array: Ar,
29
- ): Ar extends NonEmptyArray<unknown>
29
+ ): Ar extends NonEmptyTuple<unknown>
30
30
  ? IntersectBrand<PositiveNumber, SizeType.Arr>
31
31
  : SizeType.Arr =>
32
32
  // eslint-disable-next-line total-functions/no-unsafe-type-assertion
@@ -1,4 +1,9 @@
1
- import { type List, type NonEmptyArray, type SmallUint } from 'ts-type-forge';
1
+ import {
2
+ type List,
3
+ type NonEmptyArray,
4
+ type NonEmptyTuple,
5
+ type StructuralPrefixLength,
6
+ } from 'ts-type-forge';
2
7
  import { Uint32 } from '../../number/index.mjs';
3
8
  import { type SizeType } from '../../types.mjs';
4
9
  import { size } from './array-utils-size.mjs';
@@ -84,10 +89,10 @@ export function take<
84
89
  >(
85
90
  array: Ar,
86
91
  num: N,
87
- ): N extends SmallUint
92
+ ): N extends StructuralPrefixLength
88
93
  ? List.Take<N, Ar>
89
94
  : N extends SizeType.ArgArrPositive
90
- ? Ar extends NonEmptyArray<unknown>
95
+ ? Ar extends NonEmptyTuple<unknown>
91
96
  ? NonEmptyArray<Ar[number]>
92
97
  : readonly Ar[number][]
93
98
  : readonly Ar[number][];
@@ -96,10 +101,10 @@ export function take<N extends SizeType.ArgArr>(
96
101
  num: N,
97
102
  ): <const Ar extends readonly unknown[]>(
98
103
  array: Ar,
99
- ) => N extends SmallUint
104
+ ) => N extends StructuralPrefixLength
100
105
  ? List.Take<N, Ar>
101
106
  : N extends SizeType.ArgArrPositive
102
- ? Ar extends NonEmptyArray<unknown>
107
+ ? Ar extends NonEmptyTuple<unknown>
103
108
  ? NonEmptyArray<Ar[number]>
104
109
  : readonly Ar[number][]
105
110
  : readonly Ar[number][];
@@ -147,10 +152,10 @@ export function takeLast<
147
152
  >(
148
153
  array: Ar,
149
154
  num: N,
150
- ): N extends SmallUint
155
+ ): N extends StructuralPrefixLength
151
156
  ? List.TakeLast<N, Ar>
152
157
  : N extends SizeType.ArgArrPositive
153
- ? Ar extends NonEmptyArray<unknown>
158
+ ? Ar extends NonEmptyTuple<unknown>
154
159
  ? NonEmptyArray<Ar[number]>
155
160
  : readonly Ar[number][]
156
161
  : readonly Ar[number][];
@@ -159,10 +164,10 @@ export function takeLast<N extends SizeType.ArgArr>(
159
164
  num: N,
160
165
  ): <const Ar extends readonly unknown[]>(
161
166
  array: Ar,
162
- ) => N extends SmallUint
167
+ ) => N extends StructuralPrefixLength
163
168
  ? List.TakeLast<N, Ar>
164
169
  : N extends SizeType.ArgArrPositive
165
- ? Ar extends NonEmptyArray<unknown>
170
+ ? Ar extends NonEmptyTuple<unknown>
166
171
  ? NonEmptyArray<Ar[number]>
167
172
  : readonly Ar[number][]
168
173
  : readonly Ar[number][];
@@ -210,14 +215,16 @@ export function skip<
210
215
  >(
211
216
  array: Ar,
212
217
  num: N,
213
- ): N extends SmallUint ? List.Skip<N, Ar> : readonly Ar[number][];
218
+ ): N extends StructuralPrefixLength ? List.Skip<N, Ar> : readonly Ar[number][];
214
219
 
215
220
  // curried version
216
221
  export function skip<N extends SizeType.ArgArr>(
217
222
  num: N,
218
223
  ): <const Ar extends readonly unknown[]>(
219
224
  array: Ar,
220
- ) => N extends SmallUint ? List.Skip<N, Ar> : readonly Ar[number][];
225
+ ) => N extends StructuralPrefixLength
226
+ ? List.Skip<N, Ar>
227
+ : readonly Ar[number][];
221
228
 
222
229
  export function skip<E>(
223
230
  ...args: readonly [readonly E[], SizeType.ArgArr] | readonly [SizeType.ArgArr]
@@ -260,14 +267,18 @@ export function skipLast<
260
267
  >(
261
268
  array: Ar,
262
269
  num: N,
263
- ): N extends SmallUint ? List.SkipLast<N, Ar> : readonly Ar[number][];
270
+ ): N extends StructuralPrefixLength
271
+ ? List.SkipLast<N, Ar>
272
+ : readonly Ar[number][];
264
273
 
265
274
  // curried version
266
275
  export function skipLast<N extends SizeType.ArgArr>(
267
276
  num: N,
268
277
  ): <const Ar extends readonly unknown[]>(
269
278
  array: Ar,
270
- ) => N extends SmallUint ? List.SkipLast<N, Ar> : readonly Ar[number][];
279
+ ) => N extends StructuralPrefixLength
280
+ ? List.SkipLast<N, Ar>
281
+ : readonly Ar[number][];
271
282
 
272
283
  export function skipLast<E>(
273
284
  ...args:
@@ -2,8 +2,8 @@ import {
2
2
  type FixedLengthTuple,
3
3
  type IsFixedLengthList,
4
4
  type List,
5
- type MutableNonEmptyArray,
6
5
  type NonEmptyArray,
6
+ type NonEmptyTuple,
7
7
  type PositiveInt,
8
8
  type PositiveUint32,
9
9
  type Primitive,
@@ -98,9 +98,12 @@ export function map<A, B>(
98
98
  *
99
99
  * const expectedCurriedTotals = [10, 5, 20] as const;
100
100
  *
101
- * assert.deepStrictEqual(runningTotals, expectedTotals);
101
+ * assert.deepStrictEqual<readonly number[]>(runningTotals, expectedTotals);
102
102
  *
103
- * assert.deepStrictEqual(runningTotalsFromCurried, expectedCurriedTotals);
103
+ * assert.deepStrictEqual<readonly number[]>(
104
+ * runningTotalsFromCurried,
105
+ * expectedCurriedTotals,
106
+ * );
104
107
  * ```
105
108
  */
106
109
  export function scan<const Ar extends readonly unknown[], S>(
@@ -137,12 +140,12 @@ export function scan<E, S>(
137
140
  ) => S,
138
141
  init: S,
139
142
  ]
140
- ): NonEmptyArray<S> | ((array: readonly E[]) => NonEmptyArray<S>) {
143
+ ): NonEmptyTuple<S> | ((array: readonly E[]) => NonEmptyTuple<S>) {
141
144
  switch (args.length) {
142
145
  case 3: {
143
146
  const [array, reducer, init] = args;
144
147
 
145
- const mut_result: MutableNonEmptyArray<S> = castMutable(
148
+ const mut_result = castMutable<NonEmptyTuple<S>>(
146
149
  newArray<PositiveUint32, S>(asPositiveUint32(array.length + 1), init),
147
150
  );
148
151
 
@@ -221,7 +224,7 @@ export const toSorted = <const Ar extends readonly unknown[]>(
221
224
  : readonly [array: Ar, comparator: (x: Ar[number], y: Ar[number]) => number]
222
225
  ): IsFixedLengthList<Ar> extends true
223
226
  ? FixedLengthTuple<Ar['length'], Ar[number]>
224
- : Ar extends NonEmptyArray<unknown>
227
+ : Ar extends NonEmptyTuple<unknown>
225
228
  ? NonEmptyArray<Ar[number]>
226
229
  : readonly Ar[number][] =>
227
230
  // eslint-disable-next-line total-functions/no-unsafe-type-assertion
@@ -279,7 +282,7 @@ export function toSortedBy<const Ar extends readonly unknown[]>(
279
282
  comparator?: (x: number, y: number) => number,
280
283
  ): IsFixedLengthList<Ar> extends true
281
284
  ? FixedLengthTuple<Ar['length'], Ar[number]>
282
- : Ar extends NonEmptyArray<unknown>
285
+ : Ar extends NonEmptyTuple<unknown>
283
286
  ? NonEmptyArray<Ar[number]>
284
287
  : readonly Ar[number][];
285
288
 
@@ -289,7 +292,7 @@ export function toSortedBy<const Ar extends readonly unknown[], const V>(
289
292
  comparator: (x: V, y: V) => number,
290
293
  ): IsFixedLengthList<Ar> extends true
291
294
  ? FixedLengthTuple<Ar['length'], Ar[number]>
292
- : Ar extends NonEmptyArray<unknown>
295
+ : Ar extends NonEmptyTuple<unknown>
293
296
  ? NonEmptyArray<Ar[number]>
294
297
  : readonly Ar[number][];
295
298
 
@@ -434,12 +437,12 @@ export function filterNot<E>(
434
437
  *
435
438
  * const expected = ['a', 'b', 'c'] as const;
436
439
  *
437
- * assert.deepStrictEqual(uniqueLetters, expected);
440
+ * assert.deepStrictEqual<readonly string[]>(uniqueLetters, expected);
438
441
  * ```
439
442
  */
440
443
  export const uniq = <const Ar extends readonly Primitive[]>(
441
444
  array: Ar,
442
- ): Ar extends NonEmptyArray<unknown>
445
+ ): Ar extends NonEmptyTuple<unknown>
443
446
  ? NonEmptyArray<Ar[number]>
444
447
  : readonly Ar[number][] =>
445
448
  // eslint-disable-next-line total-functions/no-unsafe-type-assertion
@@ -466,7 +469,10 @@ export const uniq = <const Ar extends readonly Primitive[]>(
466
469
  * { id: 3, name: 'Grace' },
467
470
  * ] as const;
468
471
  *
469
- * assert.deepStrictEqual(uniqueById, expected);
472
+ * assert.deepStrictEqual<readonly Readonly<{ id: number; name: string }>[]>(
473
+ * uniqueById,
474
+ * expected,
475
+ * );
470
476
  * ```
471
477
  */
472
478
  export const uniqBy = <
@@ -475,7 +481,7 @@ export const uniqBy = <
475
481
  >(
476
482
  array: Ar,
477
483
  mapFn: (value: Ar[number]) => P,
478
- ): Ar extends NonEmptyArray<unknown>
484
+ ): Ar extends NonEmptyTuple<unknown>
479
485
  ? NonEmptyArray<Ar[number]>
480
486
  : readonly Ar[number][] => {
481
487
  const mut_mappedValues = new Set<P>();
@@ -73,7 +73,7 @@ describe('Arr transformations', () => {
73
73
 
74
74
  expectType<typeof runningSum, readonly [number, ...number[]]>('<=');
75
75
 
76
- assert.deepStrictEqual(runningSum, [0, 1, 3, 6, 10]);
76
+ assert.deepStrictEqual<readonly number[]>(runningSum, [0, 1, 3, 6, 10]);
77
77
  });
78
78
 
79
79
  test('should include initial value as first element', () => {
@@ -81,7 +81,7 @@ describe('Arr transformations', () => {
81
81
 
82
82
  const result = scan(numbers, (acc, curr) => acc + curr, 100);
83
83
 
84
- assert.deepStrictEqual(result, [100, 110, 130, 160]);
84
+ assert.deepStrictEqual<readonly number[]>(result, [100, 110, 130, 160]);
85
85
 
86
86
  expect(result).toHaveLength(4); // original length + 1
87
87
  });
@@ -93,9 +93,9 @@ describe('Arr transformations', () => {
93
93
 
94
94
  const result2 = scanSum([5, 10]);
95
95
 
96
- assert.deepStrictEqual(result1, [0, 1, 3, 6]);
96
+ assert.deepStrictEqual<readonly number[]>(result1, [0, 1, 3, 6]);
97
97
 
98
- assert.deepStrictEqual(result2, [0, 5, 15]);
98
+ assert.deepStrictEqual<readonly number[]>(result2, [0, 5, 15]);
99
99
  });
100
100
 
101
101
  test('should provide index to reducer', () => {
@@ -121,7 +121,7 @@ describe('Arr transformations', () => {
121
121
 
122
122
  const result = scan(empty, (acc, curr) => acc + curr, 42);
123
123
 
124
- assert.deepStrictEqual(result, [42]);
124
+ assert.deepStrictEqual<readonly number[]>(result, [42]);
125
125
  });
126
126
 
127
127
  test('should work with different accumulator and element types', () => {
@@ -131,7 +131,7 @@ describe('Arr transformations', () => {
131
131
 
132
132
  expectType<typeof result, readonly [number, ...number[]]>('<=');
133
133
 
134
- assert.deepStrictEqual(result, [0, 1, 2, 3]);
134
+ assert.deepStrictEqual<readonly number[]>(result, [0, 1, 2, 3]);
135
135
  });
136
136
 
137
137
  test('should compute running product', () => {
@@ -139,7 +139,7 @@ describe('Arr transformations', () => {
139
139
 
140
140
  const runningProduct = scan(numbers, (acc, curr) => acc * curr, 1);
141
141
 
142
- assert.deepStrictEqual(runningProduct, [1, 2, 6, 24]);
142
+ assert.deepStrictEqual<readonly number[]>(runningProduct, [1, 2, 6, 24]);
143
143
  });
144
144
 
145
145
  test('should work with objects', () => {
@@ -147,7 +147,7 @@ describe('Arr transformations', () => {
147
147
 
148
148
  const result = scan(items, (acc, curr) => acc + curr.value, 0);
149
149
 
150
- assert.deepStrictEqual(result, [0, 10, 30, 60]);
150
+ assert.deepStrictEqual<readonly number[]>(result, [0, 10, 30, 60]);
151
151
  });
152
152
 
153
153
  test('should preserve all intermediate values', () => {
@@ -156,7 +156,7 @@ describe('Arr transformations', () => {
156
156
  const result = scan(numbers, (acc, curr) => acc - curr, 10);
157
157
 
158
158
  // 10 -> 10-1=9 -> 9-2=7 -> 7-3=4
159
- assert.deepStrictEqual(result, [10, 9, 7, 4]);
159
+ assert.deepStrictEqual<readonly number[]>(result, [10, 9, 7, 4]);
160
160
  });
161
161
  });
162
162
 
@@ -429,7 +429,7 @@ describe('Arr transformations', () => {
429
429
 
430
430
  const result = uniq(array);
431
431
 
432
- assert.deepStrictEqual(result, [1, 2, 3, 4]);
432
+ assert.deepStrictEqual<readonly number[]>(result, [1, 2, 3, 4]);
433
433
  });
434
434
 
435
435
  test('should work with strings', () => {
@@ -437,7 +437,7 @@ describe('Arr transformations', () => {
437
437
 
438
438
  const result = uniq(array);
439
439
 
440
- assert.deepStrictEqual(result, ['a', 'b', 'c']);
440
+ assert.deepStrictEqual<readonly string[]>(result, ['a', 'b', 'c']);
441
441
  });
442
442
 
443
443
  test('should work with empty array', () => {
@@ -453,7 +453,7 @@ describe('Arr transformations', () => {
453
453
 
454
454
  const result = uniq(array);
455
455
 
456
- assert.deepStrictEqual(result, [3, 1, 2]);
456
+ assert.deepStrictEqual<readonly number[]>(result, [3, 1, 2]);
457
457
  });
458
458
  });
459
459
 
@@ -1,6 +1,8 @@
1
1
  export * from './array-utils-creation.mjs';
2
2
  export * from './array-utils-element-access.mjs';
3
3
  export * from './array-utils-iterators.mjs';
4
+ export * from './array-utils-length-bounded-array-cast.mjs';
5
+ export * from './array-utils-length-bounded-array-guard.mjs';
4
6
  export * from './array-utils-modification.mjs';
5
7
  export * from './array-utils-reducing-value.mjs';
6
8
  export * from './array-utils-search.mjs';
@@ -1,7 +1,4 @@
1
- export * from './as-length-bounded-array.mjs';
2
1
  export * from './has-key.mjs';
3
- export * from './is-length-bounded-array.mjs';
4
- export * from './is-length-bounded-string.mjs';
5
2
  export * from './is-non-empty-string.mjs';
6
3
  export * from './is-non-null-object.mjs';
7
4
  export * from './is-primitive.mjs';
package/src/index.mts CHANGED
@@ -7,4 +7,5 @@ export * from './number/index.mjs';
7
7
  export * from './object/index.mjs';
8
8
  export * from './others/index.mjs';
9
9
  export * from './promise/index.mjs';
10
+ export * from './string/index.mjs';
10
11
  export * from './types.mjs';
@@ -0,0 +1 @@
1
+ export * from './str.mjs';