utilitish 0.0.4 → 0.0.6
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/dist/array/array-constructor.d.ts +85 -12
- package/dist/array/array-constructor.js +32 -17
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/map/map-prototype.d.ts +1 -1
- package/dist/map/map-prototype.js +8 -1
- package/dist/utils.d.ts +98 -0
- package/dist/utils.js +107 -1
- package/package.json +4 -2
|
@@ -2,25 +2,98 @@ export {};
|
|
|
2
2
|
declare global {
|
|
3
3
|
interface ArrayConstructor {
|
|
4
4
|
/**
|
|
5
|
-
* Combines multiple arrays element-wise,
|
|
6
|
-
*
|
|
7
|
-
* @
|
|
5
|
+
* Combines multiple arrays element-wise, similar to Python's `itertools.zip_longest`.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* Array.zip([1, 2], ['a', 'b', 'c']);
|
|
9
|
+
* // => [[1, 'a'], [2, 'b'], [undefined, 'c']]
|
|
10
|
+
*
|
|
11
|
+
* @template T Type of the array elements
|
|
12
|
+
* @param {...T[][]} arrays Arrays to zip together
|
|
13
|
+
* @returns {Array<(T | undefined)[]>} A new array where each element is an array containing the elements at the same index from each input array. Missing elements are `undefined`.
|
|
8
14
|
*/
|
|
9
15
|
zip(...arrays: any[][]): any[][];
|
|
10
16
|
/**
|
|
11
|
-
* Generates a sequence of numbers, similar to Python's range
|
|
12
|
-
*
|
|
13
|
-
* @
|
|
14
|
-
*
|
|
15
|
-
*
|
|
17
|
+
* Generates a sequence of numbers, similar to Python's `range`.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* Array.range(5);
|
|
21
|
+
* // => [0, 1, 2, 3, 4]
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* Array.range(2, 10, 2);
|
|
25
|
+
* // => [2, 4, 6, 8]
|
|
26
|
+
*
|
|
27
|
+
* @param {number} start First number, or the length if `end` is not provided
|
|
28
|
+
* @param {number} [end] Last number (excluded)
|
|
29
|
+
* @param {number} [step=1] Step between numbers (can be negative)
|
|
30
|
+
* @returns {number[]} An array containing the generated sequence
|
|
16
31
|
*/
|
|
17
32
|
range(start: number, end?: number, step?: number): number[];
|
|
18
33
|
/**
|
|
19
|
-
* Creates an array filled with the same value or
|
|
20
|
-
*
|
|
21
|
-
* @
|
|
22
|
-
*
|
|
34
|
+
* Creates an array filled with the same value or with values generated by a factory function.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* Array.repeat(3, 'x');
|
|
38
|
+
* // => ['x', 'x', 'x']
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* Array.repeat(3, () => Math.random());
|
|
42
|
+
* // => [0.12, 0.45, 0.78] (values will differ)
|
|
43
|
+
*
|
|
44
|
+
* @template T Type of the array elements
|
|
45
|
+
* @param {number} length Length of the array (must be a non-negative integer)
|
|
46
|
+
* @param {T | (() => T)} value Value or function generating the value
|
|
47
|
+
* @returns {T[]} The filled array
|
|
23
48
|
*/
|
|
24
49
|
repeat<T>(length: number, value: T | (() => T)): T[];
|
|
50
|
+
/**
|
|
51
|
+
* Creates an array filled with a given value or generated using a factory function.
|
|
52
|
+
* Supports creating multi-dimensional arrays by passing multiple sizes.
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* // 1D array with primitive values
|
|
56
|
+
* const arr1 = Array.create('x', 5);
|
|
57
|
+
* // type: string[]
|
|
58
|
+
* // value: ['x', 'x', 'x', 'x', 'x']
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* // 1D array with random numbers
|
|
62
|
+
* const arr2 = Array.create(() => Math.random(), 5);
|
|
63
|
+
* // type: number[]
|
|
64
|
+
* // value: [0.12, 0.87, 0.45, 0.76, 0.33] (values will differ)
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* // 2D array (matrix)
|
|
68
|
+
* const arr3 = Array.create(0, 2, 3);
|
|
69
|
+
* // type: number[][]
|
|
70
|
+
* // value: [[0, 0, 0], [0, 0, 0]]
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* // 2D array with distinct objects
|
|
74
|
+
* const arr4 = Array.create(() => ({ id: 0 }), 2, 3);
|
|
75
|
+
* // type: { id: number }[][]
|
|
76
|
+
* // value: [
|
|
77
|
+
* // [{ id: 0 }, { id: 0 }, { id: 0 }],
|
|
78
|
+
* // [{ id: 0 }, { id: 0 }, { id: 0 }]
|
|
79
|
+
* // ]
|
|
80
|
+
*
|
|
81
|
+
* @notes
|
|
82
|
+
* - If `sizes.length === 0`, returns `[]`.
|
|
83
|
+
* - If `valueOrFactory` is a primitive, all cells contain the same value.
|
|
84
|
+
* - If `valueOrFactory` is a function, it is called for each cell to produce a fresh value.
|
|
85
|
+
* - `sizes` should be integers >= 0; negative or non-integer values are not supported.
|
|
86
|
+
*
|
|
87
|
+
* @template T
|
|
88
|
+
* @param {T | (() => T)} valueOrFactory The value to fill the array with, or a factory function producing values.
|
|
89
|
+
* @param {...number} sizes Sizes for each dimension (1D => one number, 2D => two numbers, etc.).
|
|
90
|
+
* @returns {Array} A multi-dimensional array of the specified depth filled with the given values.
|
|
91
|
+
*
|
|
92
|
+
* @remarks
|
|
93
|
+
* - This method is **static** and must be called on `Array`, not on an instance.
|
|
94
|
+
*/
|
|
95
|
+
create<T, Dims extends number[]>(valueOrFactory: T | (() => T), ...sizes: Dims): MultiDimensionalArray<WidenLiterals<T>, Dims>;
|
|
25
96
|
}
|
|
26
97
|
}
|
|
98
|
+
type MultiDimensionalArray<T, Dims extends number[]> = Dims extends [number, ...infer Rest extends number[]] ? MultiDimensionalArray<T[], Rest> : T;
|
|
99
|
+
type WidenLiterals<T> = T extends string ? string : T extends number ? number : T extends boolean ? boolean : T;
|
|
@@ -1,36 +1,51 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
|
|
3
|
+
const utils_1 = require("../utils");
|
|
4
|
+
/**
|
|
5
|
+
* @see Array.zip
|
|
6
|
+
*/
|
|
7
|
+
(0, utils_1.defineStaticIfNotExists)(Array, 'zip', function (...arrays) {
|
|
4
8
|
if (arrays.length === 0)
|
|
5
9
|
return [];
|
|
6
10
|
const maxLen = Math.max(...arrays.map((arr) => arr.length));
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
Array.range = function (start, end, step = 1) {
|
|
11
|
+
return Array.from({ length: maxLen }, (_, i) => arrays.map((arr) => arr[i]));
|
|
12
|
+
});
|
|
13
|
+
/**
|
|
14
|
+
* @see Array.range
|
|
15
|
+
*/
|
|
16
|
+
(0, utils_1.defineStaticIfNotExists)(Array, 'range', function (start, end, step = 1) {
|
|
14
17
|
if (end === undefined) {
|
|
15
18
|
end = start;
|
|
16
19
|
start = 0;
|
|
17
20
|
}
|
|
18
|
-
const result = [];
|
|
19
21
|
if (step === 0)
|
|
20
22
|
throw new Error('step must not be 0');
|
|
23
|
+
const result = [];
|
|
21
24
|
const condition = step > 0 ? (i) => i < end : (i) => i > end;
|
|
22
25
|
for (let i = start; condition(i); i += step) {
|
|
23
26
|
result.push(i);
|
|
24
27
|
}
|
|
25
28
|
return result;
|
|
26
|
-
};
|
|
27
|
-
|
|
29
|
+
});
|
|
30
|
+
/**
|
|
31
|
+
* @see Array.repeat
|
|
32
|
+
*/
|
|
33
|
+
(0, utils_1.defineStaticIfNotExists)(Array, 'repeat', function (length, value) {
|
|
28
34
|
if (typeof length !== 'number' || !Number.isInteger(length) || length < 0) {
|
|
29
|
-
throw new TypeError('
|
|
35
|
+
throw new TypeError('Length must be a non-negative integer');
|
|
30
36
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
37
|
+
return Array.from({ length }, () => (typeof value === 'function' ? value() : value));
|
|
38
|
+
});
|
|
39
|
+
/**
|
|
40
|
+
* @see Array.create
|
|
41
|
+
*/
|
|
42
|
+
(0, utils_1.defineStaticIfNotExists)(Array, 'create', function (valueOrFactory, ...sizes) {
|
|
43
|
+
if (sizes.length === 0)
|
|
44
|
+
return [];
|
|
45
|
+
if (!sizes.every((s) => Number.isInteger(s) && s >= 0)) {
|
|
46
|
+
throw new TypeError('All sizes must be non-negative integers');
|
|
34
47
|
}
|
|
35
|
-
|
|
36
|
-
};
|
|
48
|
+
const getValue = typeof valueOrFactory === 'function' ? valueOrFactory : () => valueOrFactory;
|
|
49
|
+
const createDimension = (dimIndex) => Array.from({ length: sizes[dimIndex] }, () => dimIndex === sizes.length - 1 ? getValue() : createDimension(dimIndex + 1));
|
|
50
|
+
return createDimension(0);
|
|
51
|
+
});
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -2,5 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
require("./array/array-constructor");
|
|
4
4
|
require("./array/array-prototype");
|
|
5
|
+
require("./map/map-prototype");
|
|
5
6
|
require("./object/object-prototype");
|
|
7
|
+
require("./set/set-prototype");
|
|
6
8
|
require("./string/string-prototype");
|
|
@@ -27,8 +27,15 @@ const utils_1 = require("../utils");
|
|
|
27
27
|
}
|
|
28
28
|
});
|
|
29
29
|
(0, utils_1.defineIfNotExists)(Map.prototype, 'ensureArray', function (key) {
|
|
30
|
+
if (key === null || key === undefined) {
|
|
31
|
+
throw new TypeError('Key cannot be null or undefined');
|
|
32
|
+
}
|
|
30
33
|
if (!this.has(key)) {
|
|
31
34
|
this.set(key, []);
|
|
32
35
|
}
|
|
33
|
-
|
|
36
|
+
const arr = this.get(key);
|
|
37
|
+
if (!Array.isArray(arr)) {
|
|
38
|
+
throw new TypeError('Value for the key is not an array');
|
|
39
|
+
}
|
|
40
|
+
return arr;
|
|
34
41
|
});
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,5 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Defines a **non-enumerable, non-writable, non-configurable** property on a prototype
|
|
3
|
+
* if it does not already exist, or if the existing property is writable or configurable.
|
|
4
|
+
*
|
|
5
|
+
* - Intended for instance prototype methods (e.g., `Array.prototype`, `String.prototype`).
|
|
6
|
+
* - Does **not** overwrite non-configurable and non-writable properties.
|
|
7
|
+
* - Ensures immutability and hides the property from enumeration.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* defineIfNotExists(Array.prototype, 'last', function() {
|
|
11
|
+
* return this[this.length - 1];
|
|
12
|
+
* });
|
|
13
|
+
*
|
|
14
|
+
* @template T The prototype object type (e.g., `Array.prototype`).
|
|
15
|
+
* @param {T} prototype The prototype on which to define the method.
|
|
16
|
+
* @param {string} name The name of the method to define.
|
|
17
|
+
* @param {Function} fn The function to assign as the method.
|
|
18
|
+
*
|
|
19
|
+
* @remarks
|
|
20
|
+
* Use this function to safely add prototype methods without overwriting stable or built-in ones.
|
|
21
|
+
*/
|
|
1
22
|
export declare const defineIfNotExists: <T extends object>(prototype: T, name: string, fn: Function) => void;
|
|
23
|
+
/**
|
|
24
|
+
* Defines a **static** property on a constructor if it does not already exist,
|
|
25
|
+
* or if the existing property is writable or configurable.
|
|
26
|
+
*
|
|
27
|
+
* - Only affects static properties on constructors (e.g., `Array`, `Map`).
|
|
28
|
+
* - The property is created as non-enumerable, immutable, and non-configurable.
|
|
29
|
+
* - Does **not** overwrite existing properties that are non-configurable and non-writable.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* defineStaticIfNotExists(Array, 'range', function(start: number, end?: number) {
|
|
33
|
+
* // implementation
|
|
34
|
+
* });
|
|
35
|
+
*
|
|
36
|
+
* @template T The constructor type (e.g., `typeof Array`).
|
|
37
|
+
* @param {T} constructor The constructor object on which to define the static method.
|
|
38
|
+
* @param {string} name The name of the static method to define.
|
|
39
|
+
* @param {Function} fn The function to assign as the static method.
|
|
40
|
+
*
|
|
41
|
+
* @remarks
|
|
42
|
+
* To forcefully replace an existing property, delete it first or use `Object.defineProperty` directly.
|
|
43
|
+
*/
|
|
44
|
+
export declare const defineStaticIfNotExists: <T extends object>(constructor: T, name: string, fn: Function) => void;
|
|
45
|
+
/**
|
|
46
|
+
* Resolves a selector parameter into a function that extracts a value from an item.
|
|
47
|
+
*
|
|
48
|
+
* The selector can be:
|
|
49
|
+
* - a key string of the object (returns the value at that key),
|
|
50
|
+
* - a function transforming the item to the desired value,
|
|
51
|
+
* - or undefined, in which case a fallback function must be provided.
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* const sel1 = resolveSelector<{name: string}, string>('name');
|
|
55
|
+
* sel1({name: 'Alice'}); // 'Alice'
|
|
56
|
+
*
|
|
57
|
+
* const sel2 = resolveSelector<{value: number}, number>(item => item.value * 2);
|
|
58
|
+
* sel2({value: 5}); // 10
|
|
59
|
+
*
|
|
60
|
+
* const sel3 = resolveSelector(undefined, (item) => item.toString());
|
|
61
|
+
* sel3(42); // '42'
|
|
62
|
+
*
|
|
63
|
+
* @template T The type of the input items.
|
|
64
|
+
* @template R The type of the selected value.
|
|
65
|
+
* @param {keyof T | ((item: T) => R) | undefined} selector The selector key or function.
|
|
66
|
+
* @param {(item: T, index?: number) => R} [fallback] A fallback function if no selector is provided.
|
|
67
|
+
* @param {string} [name='selector'] Name used in error messages.
|
|
68
|
+
* @returns {(item: T, index?: number) => R} The resolved selector function.
|
|
69
|
+
*
|
|
70
|
+
* @throws {TypeError} If the selector is not a function or string key.
|
|
71
|
+
* @throws {TypeError} If no selector is provided and no fallback is given.
|
|
72
|
+
*/
|
|
2
73
|
export declare function resolveSelector<T, R>(selector?: keyof T | ((item: T) => R), fallback?: (item: T, index?: number) => R, name?: string): (item: T, index?: number) => R;
|
|
74
|
+
/**
|
|
75
|
+
* Asserts that a selector parameter is valid, i.e., a function or a string.
|
|
76
|
+
*
|
|
77
|
+
* @template T The type of the input items.
|
|
78
|
+
* @template R The type of the selected value.
|
|
79
|
+
* @param {any} selector The selector to validate.
|
|
80
|
+
* @param {string} [name='selector'] The name to use in error messages.
|
|
81
|
+
*
|
|
82
|
+
* @throws {TypeError} If the selector is neither a function nor a string.
|
|
83
|
+
*
|
|
84
|
+
* @remarks
|
|
85
|
+
* Used internally by `resolveSelector` to provide clearer type safety and errors.
|
|
86
|
+
*/
|
|
3
87
|
export declare function assertValidSelector<T, R>(selector: any, name?: string): asserts selector is Selector<T, R>;
|
|
88
|
+
/**
|
|
89
|
+
* Type guard to check if a value is a string or number.
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* isNumberOrString('hello'); // true
|
|
93
|
+
* isNumberOrString(42); // true
|
|
94
|
+
* isNumberOrString(true); // false
|
|
95
|
+
*
|
|
96
|
+
* @param {unknown} value The value to test.
|
|
97
|
+
* @returns {value is string | number} True if the value is a string or number, else false.
|
|
98
|
+
*/
|
|
4
99
|
export declare function isNumberOrString(value: unknown): value is string | number;
|
|
100
|
+
/**
|
|
101
|
+
* Type for a selector: either a key of T or a function from T to K.
|
|
102
|
+
*/
|
|
5
103
|
export type Selector<T, K> = keyof T | ((item: T) => K);
|
package/dist/utils.js
CHANGED
|
@@ -1,9 +1,30 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.defineIfNotExists = void 0;
|
|
3
|
+
exports.defineStaticIfNotExists = exports.defineIfNotExists = void 0;
|
|
4
4
|
exports.resolveSelector = resolveSelector;
|
|
5
5
|
exports.assertValidSelector = assertValidSelector;
|
|
6
6
|
exports.isNumberOrString = isNumberOrString;
|
|
7
|
+
/**
|
|
8
|
+
* Defines a **non-enumerable, non-writable, non-configurable** property on a prototype
|
|
9
|
+
* if it does not already exist, or if the existing property is writable or configurable.
|
|
10
|
+
*
|
|
11
|
+
* - Intended for instance prototype methods (e.g., `Array.prototype`, `String.prototype`).
|
|
12
|
+
* - Does **not** overwrite non-configurable and non-writable properties.
|
|
13
|
+
* - Ensures immutability and hides the property from enumeration.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* defineIfNotExists(Array.prototype, 'last', function() {
|
|
17
|
+
* return this[this.length - 1];
|
|
18
|
+
* });
|
|
19
|
+
*
|
|
20
|
+
* @template T The prototype object type (e.g., `Array.prototype`).
|
|
21
|
+
* @param {T} prototype The prototype on which to define the method.
|
|
22
|
+
* @param {string} name The name of the method to define.
|
|
23
|
+
* @param {Function} fn The function to assign as the method.
|
|
24
|
+
*
|
|
25
|
+
* @remarks
|
|
26
|
+
* Use this function to safely add prototype methods without overwriting stable or built-in ones.
|
|
27
|
+
*/
|
|
7
28
|
const defineIfNotExists = (prototype, name, fn) => {
|
|
8
29
|
const descriptor = Object.getOwnPropertyDescriptor(prototype, name);
|
|
9
30
|
if (!descriptor || descriptor.writable || descriptor.configurable) {
|
|
@@ -16,6 +37,67 @@ const defineIfNotExists = (prototype, name, fn) => {
|
|
|
16
37
|
}
|
|
17
38
|
};
|
|
18
39
|
exports.defineIfNotExists = defineIfNotExists;
|
|
40
|
+
/**
|
|
41
|
+
* Defines a **static** property on a constructor if it does not already exist,
|
|
42
|
+
* or if the existing property is writable or configurable.
|
|
43
|
+
*
|
|
44
|
+
* - Only affects static properties on constructors (e.g., `Array`, `Map`).
|
|
45
|
+
* - The property is created as non-enumerable, immutable, and non-configurable.
|
|
46
|
+
* - Does **not** overwrite existing properties that are non-configurable and non-writable.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* defineStaticIfNotExists(Array, 'range', function(start: number, end?: number) {
|
|
50
|
+
* // implementation
|
|
51
|
+
* });
|
|
52
|
+
*
|
|
53
|
+
* @template T The constructor type (e.g., `typeof Array`).
|
|
54
|
+
* @param {T} constructor The constructor object on which to define the static method.
|
|
55
|
+
* @param {string} name The name of the static method to define.
|
|
56
|
+
* @param {Function} fn The function to assign as the static method.
|
|
57
|
+
*
|
|
58
|
+
* @remarks
|
|
59
|
+
* To forcefully replace an existing property, delete it first or use `Object.defineProperty` directly.
|
|
60
|
+
*/
|
|
61
|
+
const defineStaticIfNotExists = (constructor, name, fn) => {
|
|
62
|
+
const descriptor = Object.getOwnPropertyDescriptor(constructor, name);
|
|
63
|
+
if (!descriptor || descriptor.writable || descriptor.configurable) {
|
|
64
|
+
Object.defineProperty(constructor, name, {
|
|
65
|
+
value: fn,
|
|
66
|
+
enumerable: false,
|
|
67
|
+
configurable: false,
|
|
68
|
+
writable: false,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
exports.defineStaticIfNotExists = defineStaticIfNotExists;
|
|
73
|
+
/**
|
|
74
|
+
* Resolves a selector parameter into a function that extracts a value from an item.
|
|
75
|
+
*
|
|
76
|
+
* The selector can be:
|
|
77
|
+
* - a key string of the object (returns the value at that key),
|
|
78
|
+
* - a function transforming the item to the desired value,
|
|
79
|
+
* - or undefined, in which case a fallback function must be provided.
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* const sel1 = resolveSelector<{name: string}, string>('name');
|
|
83
|
+
* sel1({name: 'Alice'}); // 'Alice'
|
|
84
|
+
*
|
|
85
|
+
* const sel2 = resolveSelector<{value: number}, number>(item => item.value * 2);
|
|
86
|
+
* sel2({value: 5}); // 10
|
|
87
|
+
*
|
|
88
|
+
* const sel3 = resolveSelector(undefined, (item) => item.toString());
|
|
89
|
+
* sel3(42); // '42'
|
|
90
|
+
*
|
|
91
|
+
* @template T The type of the input items.
|
|
92
|
+
* @template R The type of the selected value.
|
|
93
|
+
* @param {keyof T | ((item: T) => R) | undefined} selector The selector key or function.
|
|
94
|
+
* @param {(item: T, index?: number) => R} [fallback] A fallback function if no selector is provided.
|
|
95
|
+
* @param {string} [name='selector'] Name used in error messages.
|
|
96
|
+
* @returns {(item: T, index?: number) => R} The resolved selector function.
|
|
97
|
+
*
|
|
98
|
+
* @throws {TypeError} If the selector is not a function or string key.
|
|
99
|
+
* @throws {TypeError} If no selector is provided and no fallback is given.
|
|
100
|
+
*/
|
|
19
101
|
function resolveSelector(selector, fallback, name = 'selector') {
|
|
20
102
|
assertValidSelector(selector);
|
|
21
103
|
if (typeof selector === 'function') {
|
|
@@ -35,12 +117,36 @@ function resolveSelector(selector, fallback, name = 'selector') {
|
|
|
35
117
|
}
|
|
36
118
|
throw new TypeError(`fallback must be given if no selector`);
|
|
37
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* Asserts that a selector parameter is valid, i.e., a function or a string.
|
|
122
|
+
*
|
|
123
|
+
* @template T The type of the input items.
|
|
124
|
+
* @template R The type of the selected value.
|
|
125
|
+
* @param {any} selector The selector to validate.
|
|
126
|
+
* @param {string} [name='selector'] The name to use in error messages.
|
|
127
|
+
*
|
|
128
|
+
* @throws {TypeError} If the selector is neither a function nor a string.
|
|
129
|
+
*
|
|
130
|
+
* @remarks
|
|
131
|
+
* Used internally by `resolveSelector` to provide clearer type safety and errors.
|
|
132
|
+
*/
|
|
38
133
|
function assertValidSelector(selector, name = 'selector') {
|
|
39
134
|
const isValid = typeof selector === 'function' || typeof selector === 'string';
|
|
40
135
|
if (selector !== undefined && !isValid) {
|
|
41
136
|
throw new TypeError(`${name} must be a function or a string key`);
|
|
42
137
|
}
|
|
43
138
|
}
|
|
139
|
+
/**
|
|
140
|
+
* Type guard to check if a value is a string or number.
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* isNumberOrString('hello'); // true
|
|
144
|
+
* isNumberOrString(42); // true
|
|
145
|
+
* isNumberOrString(true); // false
|
|
146
|
+
*
|
|
147
|
+
* @param {unknown} value The value to test.
|
|
148
|
+
* @returns {value is string | number} True if the value is a string or number, else false.
|
|
149
|
+
*/
|
|
44
150
|
function isNumberOrString(value) {
|
|
45
151
|
return typeof value === 'string' || typeof value === 'number';
|
|
46
152
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "utilitish",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
],
|
|
10
10
|
"scripts": {
|
|
11
11
|
"build": "tsc",
|
|
12
|
-
"test": "jest"
|
|
12
|
+
"test": "jest",
|
|
13
|
+
"docs": "typedoc"
|
|
13
14
|
},
|
|
14
15
|
"keywords": [
|
|
15
16
|
"typescript",
|
|
@@ -22,6 +23,7 @@
|
|
|
22
23
|
"@types/jest": "^29.5.14",
|
|
23
24
|
"jest": "^29.7.0",
|
|
24
25
|
"ts-jest": "^29.3.4",
|
|
26
|
+
"typedoc": "^0.28.10",
|
|
25
27
|
"typescript": "^5.8.3"
|
|
26
28
|
}
|
|
27
29
|
}
|