ts-data-forge 14.10.0 → 14.10.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 +5 -5
- package/dist/array/impl/array-utils-element-access.d.mts.map +1 -1
- package/dist/array/impl/array-utils-element-access.mjs +4 -4
- package/dist/array/impl/array-utils-element-access.mjs.map +1 -1
- package/dist/array/impl/array-utils-length-bounded-array-cast.d.mts +8 -8
- package/dist/array/impl/array-utils-length-bounded-array-cast.d.mts.map +1 -1
- package/dist/array/impl/array-utils-length-bounded-array-cast.mjs +28 -28
- package/dist/array/impl/array-utils-length-bounded-array-cast.mjs.map +1 -1
- package/dist/array/impl/array-utils-length-bounded-array-guard.d.mts.map +1 -1
- package/dist/array/impl/array-utils-length-bounded-array-guard.mjs +4 -4
- package/dist/array/impl/array-utils-length-bounded-array-guard.mjs.map +1 -1
- package/dist/array/impl/array-utils-length-bounded-tuple-cast.d.mts +3 -4
- package/dist/array/impl/array-utils-length-bounded-tuple-cast.d.mts.map +1 -1
- package/dist/array/impl/array-utils-length-bounded-tuple-cast.mjs +28 -29
- package/dist/array/impl/array-utils-length-bounded-tuple-cast.mjs.map +1 -1
- package/dist/array/impl/array-utils-length-bounded-tuple-guard.d.mts.map +1 -1
- package/dist/array/impl/array-utils-length-bounded-tuple-guard.mjs +3 -3
- package/dist/array/impl/array-utils-length-bounded-tuple-guard.mjs.map +1 -1
- package/dist/array/impl/array-utils-modification.d.mts +1 -1
- package/dist/array/impl/array-utils-modification.d.mts.map +1 -1
- package/dist/array/impl/array-utils-modification.mjs +15 -15
- package/dist/array/impl/array-utils-modification.mjs.map +1 -1
- package/dist/array/impl/array-utils-reducing-value.d.mts.map +1 -1
- package/dist/array/impl/array-utils-reducing-value.mjs +12 -12
- package/dist/array/impl/array-utils-reducing-value.mjs.map +1 -1
- package/dist/array/impl/array-utils-search.d.mts.map +1 -1
- package/dist/array/impl/array-utils-search.mjs +56 -56
- package/dist/array/impl/array-utils-search.mjs.map +1 -1
- package/dist/array/impl/array-utils-slicing.d.mts.map +1 -1
- package/dist/array/impl/array-utils-slicing.mjs +3 -3
- package/dist/array/impl/array-utils-slicing.mjs.map +1 -1
- package/dist/array/impl/array-utils-transformation.d.mts +25 -25
- package/dist/array/impl/array-utils-transformation.d.mts.map +1 -1
- package/dist/array/impl/array-utils-transformation.mjs +22 -22
- 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 +2 -2
- package/dist/array/impl/array-utils-validation.mjs.map +1 -1
- package/dist/collections/imap-mapped.d.mts +2 -2
- package/dist/collections/imap.d.mts +3 -4
- package/dist/collections/imap.d.mts.map +1 -1
- package/dist/collections/imap.mjs +0 -1
- package/dist/collections/imap.mjs.map +1 -1
- package/dist/collections/iset-mapped.d.mts +1 -2
- package/dist/collections/iset-mapped.d.mts.map +1 -1
- package/dist/collections/iset-mapped.mjs.map +1 -1
- package/dist/collections/iset.d.mts +4 -5
- package/dist/collections/iset.d.mts.map +1 -1
- package/dist/collections/iset.mjs +0 -1
- package/dist/collections/iset.mjs.map +1 -1
- package/dist/number/num.d.mts +2 -2
- package/dist/number/num.mjs.map +1 -1
- package/dist/object/object.d.mts +2 -2
- package/dist/others/fast-deep-equal.d.mts.map +1 -1
- package/dist/others/fast-deep-equal.mjs +10 -7
- package/dist/others/fast-deep-equal.mjs.map +1 -1
- package/dist/others/replace-equal-deep.d.mts +9 -9
- package/dist/others/replace-equal-deep.mjs +12 -12
- package/dist/others/replace-equal-deep.mjs.map +1 -1
- package/dist/string/str.d.mts +2 -2
- package/package.json +12 -12
- package/src/array/impl/array-utils-element-access.mts +11 -11
- package/src/array/impl/array-utils-length-bounded-array-cast.mts +69 -69
- package/src/array/impl/array-utils-length-bounded-array-guard.mts +21 -21
- package/src/array/impl/array-utils-length-bounded-array-guard.test.mts +2 -2
- package/src/array/impl/array-utils-length-bounded-tuple-cast.mts +64 -65
- package/src/array/impl/array-utils-length-bounded-tuple-guard.mts +15 -15
- package/src/array/impl/array-utils-modification.mts +54 -54
- package/src/array/impl/array-utils-reducing-value.mts +55 -55
- package/src/array/impl/array-utils-search.mts +114 -114
- package/src/array/impl/array-utils-slicing.mts +16 -16
- package/src/array/impl/array-utils-transformation.mts +96 -96
- package/src/array/impl/array-utils-transformation.test.mts +2 -2
- package/src/array/impl/array-utils-validation.mts +19 -19
- package/src/array/impl/array-utils-validation.test.mts +1 -1
- package/src/collections/imap-mapped.mts +2 -2
- package/src/collections/imap.mts +3 -4
- package/src/collections/imap.test.mts +1 -1
- package/src/collections/iset-mapped.mts +1 -2
- package/src/collections/iset.mts +4 -5
- package/src/collections/iset.test.mts +1 -1
- package/src/number/num.mts +10 -10
- package/src/object/object.mts +2 -2
- package/src/others/fast-deep-equal.mts +17 -10
- package/src/others/fast-deep-equal.test.mts +141 -29
- package/src/others/replace-equal-deep.mts +37 -37
- package/src/others/replace-equal-deep.test.mts +13 -7
- package/src/string/str.mts +2 -2
|
@@ -3,18 +3,18 @@
|
|
|
3
3
|
* replaced by that part of `current` (structural sharing). When the whole of
|
|
4
4
|
* `next` is deeply equal to `current`, `current` itself is returned, so an
|
|
5
5
|
* `Object.is` comparison of the result with `current` tells whether anything
|
|
6
|
-
* changed, and a reader that compares by reference sees a new object only
|
|
7
|
-
*
|
|
6
|
+
* changed, and a reader that compares by reference sees a new object only where
|
|
7
|
+
* the value really changed.
|
|
8
8
|
*
|
|
9
9
|
* Only plain objects and arrays are walked into. Anything else — a `Map`, a
|
|
10
10
|
* `Set`, a `Date`, a class instance — is compared whole with
|
|
11
11
|
* {@link fastDeepEqual} and kept or replaced whole.
|
|
12
12
|
*
|
|
13
13
|
* Array items are matched by index. Give `key` to match them by key instead:
|
|
14
|
-
* an item for which it returns something other than `undefined` is matched
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
14
|
+
* an item for which it returns something other than `undefined` is matched with
|
|
15
|
+
* the item of `current` it returns the same key for, and an item it returns
|
|
16
|
+
* `undefined` for is still matched by index. The one `key` is used for the
|
|
17
|
+
* arrays at every depth.
|
|
18
18
|
*
|
|
19
19
|
* Neither argument is changed. The result shares objects with both, so it
|
|
20
20
|
* relies on neither being changed afterwards.
|
|
@@ -86,9 +86,9 @@ export declare const replaceEqualDeep: <T>(current: T, next: T, options?: Replac
|
|
|
86
86
|
/** Options of {@link replaceEqualDeep}. */
|
|
87
87
|
export type ReplaceEqualDeepOptions = Readonly<{
|
|
88
88
|
/**
|
|
89
|
-
* The key an array item is matched by. Items it returns `undefined` for
|
|
90
|
-
*
|
|
91
|
-
*
|
|
89
|
+
* The key an array item is matched by. Items it returns `undefined` for are
|
|
90
|
+
* matched by index. Keys are compared with `SameValueZero`, as `Map` compares
|
|
91
|
+
* them.
|
|
92
92
|
*/
|
|
93
93
|
key?: (item: unknown) => unknown;
|
|
94
94
|
}>;
|
|
@@ -89,6 +89,8 @@ export const replaceEqualDeep = (current, next, options) =>
|
|
|
89
89
|
|
|
90
90
|
|
|
91
91
|
replace(current, next, options?.key);
|
|
92
|
+
const isPlainArray = (value) => Array.isArray(value) && Object.getPrototypeOf(value) === Array.prototype;
|
|
93
|
+
const isPlainObject = (value) => isRecord(value) && Object.getPrototypeOf(value) === Object.prototype;
|
|
92
94
|
const replace = (current, next, key) => Object.is(current, next)
|
|
93
95
|
? current
|
|
94
96
|
: isPlainArray(current) && isPlainArray(next)
|
|
@@ -98,6 +100,16 @@ const replace = (current, next, key) => Object.is(current, next)
|
|
|
98
100
|
: fastDeepEqual(current, next)
|
|
99
101
|
? current
|
|
100
102
|
: next;
|
|
103
|
+
const indexByKey = (items, key) => {
|
|
104
|
+
const mut_byKey = new Map();
|
|
105
|
+
for (const item of items) {
|
|
106
|
+
const itemKey = key(item);
|
|
107
|
+
if (itemKey !== undefined && !mut_byKey.has(itemKey)) {
|
|
108
|
+
mut_byKey.set(itemKey, item);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return mut_byKey;
|
|
112
|
+
};
|
|
101
113
|
|
|
102
114
|
|
|
103
115
|
|
|
@@ -141,16 +153,4 @@ const replaceObject = (current, next, key) => {
|
|
|
141
153
|
};
|
|
142
154
|
|
|
143
155
|
const absent = Symbol('absent');
|
|
144
|
-
const indexByKey = (items, key) => {
|
|
145
|
-
const mut_byKey = new Map();
|
|
146
|
-
for (const item of items) {
|
|
147
|
-
const itemKey = key(item);
|
|
148
|
-
if (itemKey !== undefined && !mut_byKey.has(itemKey)) {
|
|
149
|
-
mut_byKey.set(itemKey, item);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
return mut_byKey;
|
|
153
|
-
};
|
|
154
|
-
const isPlainArray = (value) => Array.isArray(value) && Object.getPrototypeOf(value) === Array.prototype;
|
|
155
|
-
const isPlainObject = (value) => isRecord(value) && Object.getPrototypeOf(value) === Object.prototype;
|
|
156
156
|
//# sourceMappingURL=replace-equal-deep.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"replace-equal-deep.mjs","sourceRoot":"","sources":["../../src/others/replace-equal-deep.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmFG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,OAAU,EACV,IAAO,EACP,OAAiC,EAC9B,EAAE;AACL,
|
|
1
|
+
{"version":3,"file":"replace-equal-deep.mjs","sourceRoot":"","sources":["../../src/others/replace-equal-deep.mts"],"names":[],"mappings":"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"}
|
package/dist/string/str.d.mts
CHANGED
|
@@ -321,8 +321,8 @@ export declare namespace Str {
|
|
|
321
321
|
* `NonEmptyString` is an alias of `MinLengthString<1>`, so this is the
|
|
322
322
|
* length-1 specialization of {@link asMinLengthString}. Use this instead of
|
|
323
323
|
* writing `s as unknown as NonEmptyString`: the length is verified at
|
|
324
|
-
* runtime, and the original string type (e.g. literal types) is preserved
|
|
325
|
-
*
|
|
324
|
+
* runtime, and the original string type (e.g. literal types) is preserved via
|
|
325
|
+
* intersection.
|
|
326
326
|
*
|
|
327
327
|
* @example
|
|
328
328
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ts-data-forge",
|
|
3
|
-
"version": "14.10.
|
|
3
|
+
"version": "14.10.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -43,28 +43,28 @@
|
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@emotion/react": "11.14.0",
|
|
45
45
|
"@emotion/styled": "11.14.1",
|
|
46
|
-
"@mui/material": "9.
|
|
46
|
+
"@mui/material": "9.5.0",
|
|
47
47
|
"@types/react": "19.3.0",
|
|
48
|
-
"@vitest/browser-playwright": "5.0.
|
|
49
|
-
"eslint-config-typed": "
|
|
50
|
-
"eslint-plugin-ts-fortress": "1.3.
|
|
51
|
-
"eslint-plugin-ts-type-forge": "0.8.
|
|
52
|
-
"immer": "11.
|
|
53
|
-
"playwright": "1.64.
|
|
54
|
-
"prettier": "3.9.
|
|
48
|
+
"@vitest/browser-playwright": "5.0.5",
|
|
49
|
+
"eslint-config-typed": "7.3.0",
|
|
50
|
+
"eslint-plugin-ts-fortress": "1.3.12",
|
|
51
|
+
"eslint-plugin-ts-type-forge": "0.8.17",
|
|
52
|
+
"immer": "11.2.7",
|
|
53
|
+
"playwright": "1.64.1",
|
|
54
|
+
"prettier": "3.9.10",
|
|
55
55
|
"prettier-plugin-organize-imports": "4.3.0",
|
|
56
56
|
"prettier-plugin-packagejson": "3.0.2",
|
|
57
|
-
"react": "19.3.
|
|
57
|
+
"react": "19.3.1",
|
|
58
58
|
"ts-repo-utils": "10.7.1",
|
|
59
59
|
"typedoc": "0.28.20",
|
|
60
60
|
"typedoc-github-theme": "0.4.0",
|
|
61
|
-
"vite": "8.3.
|
|
61
|
+
"vite": "8.3.5"
|
|
62
62
|
},
|
|
63
63
|
"peerDependencies": {
|
|
64
64
|
"typescript": ">=4.8"
|
|
65
65
|
},
|
|
66
66
|
"engines": {
|
|
67
|
-
"node": ">=22.
|
|
67
|
+
"node": ">=22.23.4",
|
|
68
68
|
"pnpm": ">=9.0.0"
|
|
69
69
|
},
|
|
70
70
|
"publishConfig": {
|
|
@@ -53,17 +53,6 @@ export function at<E>(
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
const atImpl = <E,>(
|
|
57
|
-
array: readonly E[],
|
|
58
|
-
index: SizeType.ArgArrWithNegative,
|
|
59
|
-
): Optional<E> =>
|
|
60
|
-
pipe(index < 0 ? array.length + index : index).map((normalizedIndex) =>
|
|
61
|
-
normalizedIndex < 0 || array.length <= normalizedIndex
|
|
62
|
-
? Optional.none
|
|
63
|
-
: // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
64
|
-
Optional.some(array[normalizedIndex]!),
|
|
65
|
-
).value;
|
|
66
|
-
|
|
67
56
|
/**
|
|
68
57
|
* Returns the first element of an array as an Optional.
|
|
69
58
|
*
|
|
@@ -126,6 +115,17 @@ export const last = <const Ar extends readonly unknown[]>(
|
|
|
126
115
|
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
|
|
127
116
|
(array.length === 0 ? Optional.none : Optional.some(array.at(-1))) as never;
|
|
128
117
|
|
|
118
|
+
const atImpl = <E,>(
|
|
119
|
+
array: readonly E[],
|
|
120
|
+
index: SizeType.ArgArrWithNegative,
|
|
121
|
+
): Optional<E> =>
|
|
122
|
+
pipe(index < 0 ? array.length + index : index).map((normalizedIndex) =>
|
|
123
|
+
normalizedIndex < 0 || array.length <= normalizedIndex
|
|
124
|
+
? Optional.none
|
|
125
|
+
: // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
126
|
+
Optional.some(array[normalizedIndex]!),
|
|
127
|
+
).value;
|
|
128
|
+
|
|
129
129
|
/**
|
|
130
130
|
* Alias for `head`.
|
|
131
131
|
*
|
|
@@ -18,8 +18,8 @@ import {
|
|
|
18
18
|
* exactly `length` elements.
|
|
19
19
|
*
|
|
20
20
|
* Use this instead of writing `xs as unknown as FixedLengthArray<N, E>`: the
|
|
21
|
-
* length is verified at runtime, and the original array type (e.g. tuple
|
|
22
|
-
*
|
|
21
|
+
* length is verified at runtime, and the original array type (e.g. tuple types)
|
|
22
|
+
* is preserved via intersection, so the result also benefits from the
|
|
23
23
|
* structural tuple prefix (in-range indexed access without `undefined` under
|
|
24
24
|
* `noUncheckedIndexedAccess`).
|
|
25
25
|
*
|
|
@@ -83,28 +83,13 @@ export function asFixedLengthArray<E>(
|
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
const asFixedLengthArrayImpl = <E,>(
|
|
87
|
-
length: SupportedLength,
|
|
88
|
-
xs: readonly E[],
|
|
89
|
-
): readonly E[] => {
|
|
90
|
-
const actualLength = xs.length;
|
|
91
|
-
|
|
92
|
-
if (!isFixedLengthArray(length, xs)) {
|
|
93
|
-
throw new TypeError(
|
|
94
|
-
`Expected an array of length ${length}, got an array of length ${actualLength}`,
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return xs;
|
|
99
|
-
};
|
|
100
|
-
|
|
101
86
|
/**
|
|
102
87
|
* Casts an array to `MinLengthArray<MinLength, E>` after checking that it has
|
|
103
88
|
* at least `minLength` elements.
|
|
104
89
|
*
|
|
105
90
|
* Use this instead of writing `xs as unknown as MinLengthArray<N, E>`: the
|
|
106
|
-
* length is verified at runtime, and the original array type (e.g. tuple
|
|
107
|
-
*
|
|
91
|
+
* length is verified at runtime, and the original array type (e.g. tuple types)
|
|
92
|
+
* is preserved via intersection, so the result also benefits from the
|
|
108
93
|
* structural tuple prefix (indexed access below `min(N, 10)` without
|
|
109
94
|
* `undefined` under `noUncheckedIndexedAccess`).
|
|
110
95
|
*
|
|
@@ -168,28 +153,13 @@ export function asMinLengthArray<E>(
|
|
|
168
153
|
}
|
|
169
154
|
}
|
|
170
155
|
|
|
171
|
-
const asMinLengthArrayImpl = <E,>(
|
|
172
|
-
minLength: SupportedLength,
|
|
173
|
-
xs: readonly E[],
|
|
174
|
-
): readonly E[] => {
|
|
175
|
-
const actualLength = xs.length;
|
|
176
|
-
|
|
177
|
-
if (!isMinLengthArray(minLength, xs)) {
|
|
178
|
-
throw new TypeError(
|
|
179
|
-
`Expected an array of length >= ${minLength}, got an array of length ${actualLength}`,
|
|
180
|
-
);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
return xs;
|
|
184
|
-
};
|
|
185
|
-
|
|
186
156
|
/**
|
|
187
157
|
* Casts an array to `MaxLengthArray<MaxLength, E>` after checking that it has
|
|
188
158
|
* at most `maxLength` elements.
|
|
189
159
|
*
|
|
190
160
|
* Use this instead of writing `xs as unknown as MaxLengthArray<N, E>`: the
|
|
191
|
-
* length is verified at runtime, and the original array type (e.g. tuple
|
|
192
|
-
*
|
|
161
|
+
* length is verified at runtime, and the original array type (e.g. tuple types)
|
|
162
|
+
* is preserved via intersection.
|
|
193
163
|
*
|
|
194
164
|
* The length argument comes first, matching the type-parameter order of
|
|
195
165
|
* `MaxLengthArray<MaxLength, Elm>`. Omitting the array returns a function that
|
|
@@ -247,29 +217,14 @@ export function asMaxLengthArray<E>(
|
|
|
247
217
|
}
|
|
248
218
|
}
|
|
249
219
|
|
|
250
|
-
const asMaxLengthArrayImpl = <E,>(
|
|
251
|
-
maxLength: SupportedLength,
|
|
252
|
-
xs: readonly E[],
|
|
253
|
-
): readonly E[] => {
|
|
254
|
-
const actualLength = xs.length;
|
|
255
|
-
|
|
256
|
-
if (!isMaxLengthArray(maxLength, xs)) {
|
|
257
|
-
throw new TypeError(
|
|
258
|
-
`Expected an array of length <= ${maxLength}, got an array of length ${actualLength}`,
|
|
259
|
-
);
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
return xs;
|
|
263
|
-
};
|
|
264
|
-
|
|
265
220
|
/**
|
|
266
221
|
* Casts an array to `BoundedLengthArray<MinLength, MaxLength, E>` after
|
|
267
222
|
* checking that its length is within the inclusive range
|
|
268
223
|
* `[minLength, maxLength]`.
|
|
269
224
|
*
|
|
270
225
|
* Use this instead of writing
|
|
271
|
-
* `xs as unknown as BoundedLengthArray<Min, Max, E>`: the length is verified
|
|
272
|
-
*
|
|
226
|
+
* `xs as unknown as BoundedLengthArray<Min, Max, E>`: the length is verified at
|
|
227
|
+
* runtime, and the original array type (e.g. tuple types) is preserved via
|
|
273
228
|
* intersection.
|
|
274
229
|
*
|
|
275
230
|
* The length arguments come first, matching the type-parameter order of
|
|
@@ -344,22 +299,6 @@ export function asBoundedLengthArray<E>(
|
|
|
344
299
|
}
|
|
345
300
|
}
|
|
346
301
|
|
|
347
|
-
const asBoundedLengthArrayImpl = <E,>(
|
|
348
|
-
minLength: SupportedLength,
|
|
349
|
-
maxLength: SupportedLength,
|
|
350
|
-
xs: readonly E[],
|
|
351
|
-
): readonly E[] => {
|
|
352
|
-
const actualLength = xs.length;
|
|
353
|
-
|
|
354
|
-
if (!isBoundedLengthArray(minLength, maxLength, xs)) {
|
|
355
|
-
throw new TypeError(
|
|
356
|
-
`Expected an array of length in [${minLength}, ${maxLength}], got an array of length ${actualLength}`,
|
|
357
|
-
);
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
return xs;
|
|
361
|
-
};
|
|
362
|
-
|
|
363
302
|
/**
|
|
364
303
|
* Casts an array to `FixedLengthArray<0, E>` after checking that it is empty.
|
|
365
304
|
*
|
|
@@ -434,3 +373,64 @@ export const asNonEmptyArray = <Xs extends readonly unknown[]>(
|
|
|
434
373
|
|
|
435
374
|
return xs;
|
|
436
375
|
};
|
|
376
|
+
|
|
377
|
+
const asFixedLengthArrayImpl = <E,>(
|
|
378
|
+
length: SupportedLength,
|
|
379
|
+
xs: readonly E[],
|
|
380
|
+
): readonly E[] => {
|
|
381
|
+
const actualLength = xs.length;
|
|
382
|
+
|
|
383
|
+
if (!isFixedLengthArray(length, xs)) {
|
|
384
|
+
throw new TypeError(
|
|
385
|
+
`Expected an array of length ${length}, got an array of length ${actualLength}`,
|
|
386
|
+
);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
return xs;
|
|
390
|
+
};
|
|
391
|
+
|
|
392
|
+
const asMinLengthArrayImpl = <E,>(
|
|
393
|
+
minLength: SupportedLength,
|
|
394
|
+
xs: readonly E[],
|
|
395
|
+
): readonly E[] => {
|
|
396
|
+
const actualLength = xs.length;
|
|
397
|
+
|
|
398
|
+
if (!isMinLengthArray(minLength, xs)) {
|
|
399
|
+
throw new TypeError(
|
|
400
|
+
`Expected an array of length >= ${minLength}, got an array of length ${actualLength}`,
|
|
401
|
+
);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
return xs;
|
|
405
|
+
};
|
|
406
|
+
|
|
407
|
+
const asMaxLengthArrayImpl = <E,>(
|
|
408
|
+
maxLength: SupportedLength,
|
|
409
|
+
xs: readonly E[],
|
|
410
|
+
): readonly E[] => {
|
|
411
|
+
const actualLength = xs.length;
|
|
412
|
+
|
|
413
|
+
if (!isMaxLengthArray(maxLength, xs)) {
|
|
414
|
+
throw new TypeError(
|
|
415
|
+
`Expected an array of length <= ${maxLength}, got an array of length ${actualLength}`,
|
|
416
|
+
);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
return xs;
|
|
420
|
+
};
|
|
421
|
+
|
|
422
|
+
const asBoundedLengthArrayImpl = <E,>(
|
|
423
|
+
minLength: SupportedLength,
|
|
424
|
+
maxLength: SupportedLength,
|
|
425
|
+
xs: readonly E[],
|
|
426
|
+
): readonly E[] => {
|
|
427
|
+
const actualLength = xs.length;
|
|
428
|
+
|
|
429
|
+
if (!isBoundedLengthArray(minLength, maxLength, xs)) {
|
|
430
|
+
throw new TypeError(
|
|
431
|
+
`Expected an array of length in [${minLength}, ${maxLength}], got an array of length ${actualLength}`,
|
|
432
|
+
);
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
return xs;
|
|
436
|
+
};
|
|
@@ -85,11 +85,6 @@ export function isMinLengthArray(
|
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
const hasMinLength = (
|
|
89
|
-
minLength: SupportedLength,
|
|
90
|
-
xs: readonly unknown[],
|
|
91
|
-
): boolean => xs.length >= minLength;
|
|
92
|
-
|
|
93
88
|
/**
|
|
94
89
|
* Type guard that checks if an array has at most `maxLength` elements.
|
|
95
90
|
*
|
|
@@ -169,11 +164,6 @@ export function isMaxLengthArray(
|
|
|
169
164
|
}
|
|
170
165
|
}
|
|
171
166
|
|
|
172
|
-
const hasMaxLength = (
|
|
173
|
-
maxLength: SupportedLength,
|
|
174
|
-
xs: readonly unknown[],
|
|
175
|
-
): boolean => xs.length <= maxLength;
|
|
176
|
-
|
|
177
167
|
/**
|
|
178
168
|
* Type guard that checks if an array's length is within the inclusive range
|
|
179
169
|
* `[minLength, maxLength]`.
|
|
@@ -267,12 +257,6 @@ export function isBoundedLengthArray(
|
|
|
267
257
|
}
|
|
268
258
|
}
|
|
269
259
|
|
|
270
|
-
const hasBoundedLength = (
|
|
271
|
-
minLength: SupportedLength,
|
|
272
|
-
maxLength: SupportedLength,
|
|
273
|
-
xs: readonly unknown[],
|
|
274
|
-
): boolean => minLength <= xs.length && xs.length <= maxLength;
|
|
275
|
-
|
|
276
260
|
/**
|
|
277
261
|
* Type guard that checks if an array has exactly `length` elements.
|
|
278
262
|
*
|
|
@@ -350,11 +334,6 @@ export function isFixedLengthArray(
|
|
|
350
334
|
}
|
|
351
335
|
}
|
|
352
336
|
|
|
353
|
-
const hasFixedLength = (
|
|
354
|
-
length: SupportedLength,
|
|
355
|
-
xs: readonly unknown[],
|
|
356
|
-
): boolean => xs.length === length;
|
|
357
|
-
|
|
358
337
|
/**
|
|
359
338
|
* Type guard that checks if an array is empty.
|
|
360
339
|
*
|
|
@@ -402,3 +381,24 @@ export const isEmpty = <Xs extends readonly unknown[]>(
|
|
|
402
381
|
export const isNonEmpty = <Xs extends readonly unknown[]>(
|
|
403
382
|
array: Xs,
|
|
404
383
|
): array is MinLengthArray<1, Xs[number]> & Xs => array.length > 0;
|
|
384
|
+
|
|
385
|
+
const hasMinLength = (
|
|
386
|
+
minLength: SupportedLength,
|
|
387
|
+
xs: readonly unknown[],
|
|
388
|
+
): boolean => xs.length >= minLength;
|
|
389
|
+
|
|
390
|
+
const hasMaxLength = (
|
|
391
|
+
maxLength: SupportedLength,
|
|
392
|
+
xs: readonly unknown[],
|
|
393
|
+
): boolean => xs.length <= maxLength;
|
|
394
|
+
|
|
395
|
+
const hasBoundedLength = (
|
|
396
|
+
minLength: SupportedLength,
|
|
397
|
+
maxLength: SupportedLength,
|
|
398
|
+
xs: readonly unknown[],
|
|
399
|
+
): boolean => minLength <= xs.length && xs.length <= maxLength;
|
|
400
|
+
|
|
401
|
+
const hasFixedLength = (
|
|
402
|
+
length: SupportedLength,
|
|
403
|
+
xs: readonly unknown[],
|
|
404
|
+
): boolean => xs.length === length;
|
|
@@ -166,8 +166,8 @@ describe(isFixedLengthArray, () => {
|
|
|
166
166
|
|
|
167
167
|
expectType<typeof value, FixedLengthArray<4, number>>('!<=');
|
|
168
168
|
|
|
169
|
-
// `length` is narrowed to the literal and in-range indexed access does
|
|
170
|
-
//
|
|
169
|
+
// `length` is narrowed to the literal and in-range indexed access does not
|
|
170
|
+
// include `undefined` (even under `noUncheckedIndexedAccess`)
|
|
171
171
|
const _len = value.length;
|
|
172
172
|
|
|
173
173
|
expectType<typeof _len, 3>('=');
|
|
@@ -18,8 +18,8 @@ import {
|
|
|
18
18
|
* exactly `length` elements.
|
|
19
19
|
*
|
|
20
20
|
* This is the structural counterpart of `asFixedLengthArray`: it produces a
|
|
21
|
-
* tuple type rather than the branded `FixedLengthArray`. Prefer the branded
|
|
22
|
-
*
|
|
21
|
+
* tuple type rather than the branded `FixedLengthArray`. Prefer the branded one
|
|
22
|
+
* unless you specifically need the structural type — the brand keeps
|
|
23
23
|
* type-checking cost independent of the element type and of the bound.
|
|
24
24
|
*
|
|
25
25
|
* The length argument comes first, matching the type-parameter order of
|
|
@@ -76,21 +76,6 @@ export function asFixedLengthTuple(
|
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
const asFixedLengthTupleImpl = (
|
|
80
|
-
length: SizeType.ArgArr,
|
|
81
|
-
xs: readonly unknown[],
|
|
82
|
-
): readonly unknown[] => {
|
|
83
|
-
const actualLength = xs.length;
|
|
84
|
-
|
|
85
|
-
if (!isFixedLengthTuple(length, xs)) {
|
|
86
|
-
throw new TypeError(
|
|
87
|
-
`Expected an array of length ${length}, got an array of length ${actualLength}`,
|
|
88
|
-
);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
return xs;
|
|
92
|
-
};
|
|
93
|
-
|
|
94
79
|
/**
|
|
95
80
|
* Casts an array to `MinLengthTuple<MinLength, E>` after checking that it has
|
|
96
81
|
* at least `minLength` elements.
|
|
@@ -148,21 +133,6 @@ export function asMinLengthTuple(
|
|
|
148
133
|
}
|
|
149
134
|
}
|
|
150
135
|
|
|
151
|
-
const asMinLengthTupleImpl = (
|
|
152
|
-
minLength: SizeType.ArgArr,
|
|
153
|
-
xs: readonly unknown[],
|
|
154
|
-
): readonly unknown[] => {
|
|
155
|
-
const actualLength = xs.length;
|
|
156
|
-
|
|
157
|
-
if (!isMinLengthTuple(minLength, xs)) {
|
|
158
|
-
throw new TypeError(
|
|
159
|
-
`Expected an array of length >= ${minLength}, got an array of length ${actualLength}`,
|
|
160
|
-
);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
return xs;
|
|
164
|
-
};
|
|
165
|
-
|
|
166
136
|
/**
|
|
167
137
|
* Casts an array to `MaxLengthTuple<MaxLength, E>` after checking that it has
|
|
168
138
|
* at most `maxLength` elements.
|
|
@@ -218,21 +188,6 @@ export function asMaxLengthTuple(
|
|
|
218
188
|
}
|
|
219
189
|
}
|
|
220
190
|
|
|
221
|
-
const asMaxLengthTupleImpl = (
|
|
222
|
-
maxLength: SizeType.ArgArr,
|
|
223
|
-
xs: readonly unknown[],
|
|
224
|
-
): readonly unknown[] => {
|
|
225
|
-
const actualLength = xs.length;
|
|
226
|
-
|
|
227
|
-
if (!isMaxLengthTuple(maxLength, xs)) {
|
|
228
|
-
throw new TypeError(
|
|
229
|
-
`Expected an array of length <= ${maxLength}, got an array of length ${actualLength}`,
|
|
230
|
-
);
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
return xs;
|
|
234
|
-
};
|
|
235
|
-
|
|
236
191
|
/**
|
|
237
192
|
* Casts an array to `BoundedLengthTuple<Min, Max, E>` after checking that its
|
|
238
193
|
* length is within the inclusive range `[min, max]`.
|
|
@@ -299,25 +254,8 @@ export function asBoundedLengthTuple(
|
|
|
299
254
|
}
|
|
300
255
|
}
|
|
301
256
|
|
|
302
|
-
const asBoundedLengthTupleImpl = (
|
|
303
|
-
min: SizeType.ArgArr,
|
|
304
|
-
max: SizeType.ArgArr,
|
|
305
|
-
xs: readonly unknown[],
|
|
306
|
-
): readonly unknown[] => {
|
|
307
|
-
const actualLength = xs.length;
|
|
308
|
-
|
|
309
|
-
if (!isBoundedLengthTuple(min, max, xs)) {
|
|
310
|
-
throw new TypeError(
|
|
311
|
-
`Expected an array of length in [${min}, ${max}], got an array of length ${actualLength}`,
|
|
312
|
-
);
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
return xs;
|
|
316
|
-
};
|
|
317
|
-
|
|
318
257
|
/**
|
|
319
|
-
* Casts an array to the structural empty tuple after checking that it is
|
|
320
|
-
* empty.
|
|
258
|
+
* Casts an array to the structural empty tuple after checking that it is empty.
|
|
321
259
|
*
|
|
322
260
|
* This is the structural counterpart of `asEmptyArray`, and the length-0
|
|
323
261
|
* specialization of {@link asFixedLengthTuple}.
|
|
@@ -382,3 +320,64 @@ export const asNonEmptyTuple = <Xs extends readonly unknown[]>(
|
|
|
382
320
|
|
|
383
321
|
return xs;
|
|
384
322
|
};
|
|
323
|
+
|
|
324
|
+
const asFixedLengthTupleImpl = (
|
|
325
|
+
length: SizeType.ArgArr,
|
|
326
|
+
xs: readonly unknown[],
|
|
327
|
+
): readonly unknown[] => {
|
|
328
|
+
const actualLength = xs.length;
|
|
329
|
+
|
|
330
|
+
if (!isFixedLengthTuple(length, xs)) {
|
|
331
|
+
throw new TypeError(
|
|
332
|
+
`Expected an array of length ${length}, got an array of length ${actualLength}`,
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
return xs;
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
const asMinLengthTupleImpl = (
|
|
340
|
+
minLength: SizeType.ArgArr,
|
|
341
|
+
xs: readonly unknown[],
|
|
342
|
+
): readonly unknown[] => {
|
|
343
|
+
const actualLength = xs.length;
|
|
344
|
+
|
|
345
|
+
if (!isMinLengthTuple(minLength, xs)) {
|
|
346
|
+
throw new TypeError(
|
|
347
|
+
`Expected an array of length >= ${minLength}, got an array of length ${actualLength}`,
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
return xs;
|
|
352
|
+
};
|
|
353
|
+
|
|
354
|
+
const asMaxLengthTupleImpl = (
|
|
355
|
+
maxLength: SizeType.ArgArr,
|
|
356
|
+
xs: readonly unknown[],
|
|
357
|
+
): readonly unknown[] => {
|
|
358
|
+
const actualLength = xs.length;
|
|
359
|
+
|
|
360
|
+
if (!isMaxLengthTuple(maxLength, xs)) {
|
|
361
|
+
throw new TypeError(
|
|
362
|
+
`Expected an array of length <= ${maxLength}, got an array of length ${actualLength}`,
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
return xs;
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
const asBoundedLengthTupleImpl = (
|
|
370
|
+
min: SizeType.ArgArr,
|
|
371
|
+
max: SizeType.ArgArr,
|
|
372
|
+
xs: readonly unknown[],
|
|
373
|
+
): readonly unknown[] => {
|
|
374
|
+
const actualLength = xs.length;
|
|
375
|
+
|
|
376
|
+
if (!isBoundedLengthTuple(min, max, xs)) {
|
|
377
|
+
throw new TypeError(
|
|
378
|
+
`Expected an array of length in [${min}, ${max}], got an array of length ${actualLength}`,
|
|
379
|
+
);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
return xs;
|
|
383
|
+
};
|