@germondai/ts-utils 0.0.5 → 0.1.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.
@@ -0,0 +1,163 @@
1
+ /**
2
+ * Determines whether an array contains duplicate values.
3
+ *
4
+ * @param array - The array to check for duplicates.
5
+ * @param keyExtractor - Optional function to extract a key for comparison. If provided, duplicates are determined based on the extracted key.
6
+ * @returns True if the array contains duplicates, false otherwise.
7
+ *
8
+ * @example
9
+ * // Basic usage with primitive values
10
+ * hasDuplicates([1, 2, 3, 4, 1]); // true
11
+ * hasDuplicates(['a', 'b', 'c']); // false
12
+ *
13
+ * // Usage with objects and a key extractor
14
+ * hasDuplicates([{ id: 1 }, { id: 2 }, { id: 1 }], (item) => item.id); // true
15
+ */
16
+ export declare const hasDuplicates: <T>(array: T[], keyExtractor?: (value: T, index: number, array: T[]) => string | number) => boolean;
17
+ /**
18
+ * Removes duplicates from an array based on a key function.
19
+ *
20
+ * @param array - The array to process.
21
+ * @param keyExtractor - Function to generate a unique key for each item.
22
+ * @returns A new array without duplicates.
23
+ */
24
+ /**
25
+ * Returns a new array containing only unique elements from the input array.
26
+ * Uniqueness is determined based on the values returned by the `keyExtractor` function,
27
+ * or by the elements themselves if no `keyExtractor` is provided.
28
+ *
29
+ * @typeParam T - The type of elements in the input array.
30
+ * @param array - The input array from which to extract unique elements.
31
+ * @param keyExtractor - An optional function that extracts a key from each element
32
+ * to determine uniqueness. If not provided, the elements themselves are used.
33
+ * The function receives the current element, its index, and the entire array as arguments.
34
+ * @returns A new array containing only unique elements from the input array.
35
+ *
36
+ * @example
37
+ * // Using default behavior (elements themselves determine uniqueness)
38
+ * const numbers = [1, 2, 2, 3, 4, 4];
39
+ * const uniqueNumbers = uniqueArray(numbers);
40
+ * console.log(uniqueNumbers); // Output: [1, 2, 3, 4]
41
+ *
42
+ * @example
43
+ * // Using a keyExtractor to determine uniqueness
44
+ * const users = [
45
+ * { id: 1, name: 'Alice' },
46
+ * { id: 2, name: 'Bob' },
47
+ * { id: 1, name: 'Alice' },
48
+ * ];
49
+ * const uniqueUsers = uniqueArray(users, user => user.id);
50
+ * console.log(uniqueUsers);
51
+ * // Output: [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }]
52
+ */
53
+ export declare const uniqueArray: <T>(array: T[], keyExtractor?: (value: T, index: number, array: T[]) => string | number) => T[];
54
+ /**
55
+ * Splits an array into chunks of the specified size.
56
+ *
57
+ * @param array - The array to split.
58
+ * @param size - The size of each chunk.
59
+ * @returns An array of chunks.
60
+ *
61
+ * @example
62
+ * chunk([1, 2, 3, 4, 5], 2) // [[1, 2], [3, 4], [5]]
63
+ */
64
+ export declare const chunk: <T>(array: T[], size: number) => T[][];
65
+ /**
66
+ * Returns a new array with elements shuffled using the Fisher-Yates algorithm.
67
+ *
68
+ * @param array - The array to shuffle.
69
+ * @returns A new shuffled array.
70
+ *
71
+ * @example
72
+ * shuffle([1, 2, 3, 4, 5]) // [3, 1, 5, 2, 4] (random order)
73
+ */
74
+ export declare const shuffle: <T>(array: T[]) => T[];
75
+ /**
76
+ * Groups array elements by a key or function.
77
+ *
78
+ * @param array - The array to group.
79
+ * @param key - A property key or function to determine the group.
80
+ * @returns An object with groups as keys and arrays of items as values.
81
+ *
82
+ * @example
83
+ * groupBy([{ type: 'a', v: 1 }, { type: 'b', v: 2 }, { type: 'a', v: 3 }], 'type')
84
+ * // { a: [{ type: 'a', v: 1 }, { type: 'a', v: 3 }], b: [{ type: 'b', v: 2 }] }
85
+ */
86
+ export declare const groupBy: <T>(array: T[], key: keyof T | ((item: T) => string)) => Record<string, T[]>;
87
+ /**
88
+ * Returns elements common to all provided arrays.
89
+ *
90
+ * @param arrays - The arrays to intersect.
91
+ * @returns An array of common elements.
92
+ *
93
+ * @example
94
+ * intersection([1, 2, 3], [2, 3, 4], [3, 4, 5]) // [3]
95
+ */
96
+ export declare const intersection: <T>(...arrays: T[][]) => T[];
97
+ /**
98
+ * Returns elements that are in the first array but not in the second.
99
+ *
100
+ * @param a - The source array.
101
+ * @param b - The array of elements to exclude.
102
+ * @returns A new array with elements from `a` not found in `b`.
103
+ *
104
+ * @example
105
+ * difference([1, 2, 3, 4], [2, 4]) // [1, 3]
106
+ */
107
+ export declare const difference: <T>(a: T[], b: T[]) => T[];
108
+ /**
109
+ * Generates an array of numbers in a given range.
110
+ *
111
+ * @param start - The start of the range.
112
+ * @param end - The end of the range (exclusive).
113
+ * @param step - The step between numbers (default: 1).
114
+ * @returns An array of numbers.
115
+ *
116
+ * @example
117
+ * range(0, 5) // [0, 1, 2, 3, 4]
118
+ * range(0, 10, 3) // [0, 3, 6, 9]
119
+ */
120
+ export declare const range: (start: number, end: number, step?: number) => number[];
121
+ /**
122
+ * Returns a new sorted array by a key or comparator function.
123
+ *
124
+ * @param array - The array to sort.
125
+ * @param key - A property key or function returning a comparable value.
126
+ * @param order - Sort order: 'asc' (default) or 'desc'.
127
+ * @returns A new sorted array.
128
+ *
129
+ * @example
130
+ * sortBy([{ age: 30 }, { age: 20 }], 'age') // [{ age: 20 }, { age: 30 }]
131
+ */
132
+ export declare const sortBy: <T>(array: T[], key: keyof T | ((item: T) => number | string), order?: "asc" | "desc") => T[];
133
+ /**
134
+ * Removes all falsy values from an array.
135
+ *
136
+ * @param array - The array to compact.
137
+ * @returns A new array with falsy values removed.
138
+ *
139
+ * @example
140
+ * compact([0, 1, false, 2, '', 3, null, undefined]) // [1, 2, 3]
141
+ */
142
+ export declare const compact: <T>(array: (T | null | undefined | false | 0 | "")[]) => T[];
143
+ /**
144
+ * Returns the last element of an array.
145
+ *
146
+ * @param array - The array.
147
+ * @returns The last element, or undefined if empty.
148
+ *
149
+ * @example
150
+ * last([1, 2, 3]) // 3
151
+ * last([]) // undefined
152
+ */
153
+ export declare const last: <T>(array: T[]) => T | undefined;
154
+ /**
155
+ * Returns a random element from an array.
156
+ *
157
+ * @param array - The array.
158
+ * @returns A random element, or undefined if empty.
159
+ *
160
+ * @example
161
+ * sample([1, 2, 3]) // 2 (random)
162
+ */
163
+ export declare const sample: <T>(array: T[]) => T | undefined;
@@ -1,53 +1 @@
1
- /**
2
- * Determines whether an array contains duplicate values.
3
- *
4
- * @param array - The array to check for duplicates.
5
- * @param keyExtractor - Optional function to extract a key for comparison. If provided, duplicates are determined based on the extracted key.
6
- * @returns True if the array contains duplicates, false otherwise.
7
- *
8
- * @example
9
- * // Basic usage with primitive values
10
- * hasDuplicates([1, 2, 3, 4, 1]); // true
11
- * hasDuplicates(['a', 'b', 'c']); // false
12
- *
13
- * // Usage with objects and a key extractor
14
- * hasDuplicates([{ id: 1 }, { id: 2 }, { id: 1 }], (item) => item.id); // true
15
- */
16
- export declare const hasDuplicates: <T>(array: T[], keyExtractor?: (value: T, index: number, array: T[]) => string | number) => boolean;
17
- /**
18
- * Removes duplicates from an array based on a key function.
19
- *
20
- * @param array - The array to process.
21
- * @param keyExtractor - Function to generate a unique key for each item.
22
- * @returns A new array without duplicates.
23
- */
24
- /**
25
- * Returns a new array containing only unique elements from the input array.
26
- * Uniqueness is determined based on the values returned by the `keyExtractor` function,
27
- * or by the elements themselves if no `keyExtractor` is provided.
28
- *
29
- * @typeParam T - The type of elements in the input array.
30
- * @param array - The input array from which to extract unique elements.
31
- * @param keyExtractor - An optional function that extracts a key from each element
32
- * to determine uniqueness. If not provided, the elements themselves are used.
33
- * The function receives the current element, its index, and the entire array as arguments.
34
- * @returns A new array containing only unique elements from the input array.
35
- *
36
- * @example
37
- * // Using default behavior (elements themselves determine uniqueness)
38
- * const numbers = [1, 2, 2, 3, 4, 4];
39
- * const uniqueNumbers = uniqueArray(numbers);
40
- * console.log(uniqueNumbers); // Output: [1, 2, 3, 4]
41
- *
42
- * @example
43
- * // Using a keyExtractor to determine uniqueness
44
- * const users = [
45
- * { id: 1, name: 'Alice' },
46
- * { id: 2, name: 'Bob' },
47
- * { id: 1, name: 'Alice' },
48
- * ];
49
- * const uniqueUsers = uniqueArray(users, user => user.id);
50
- * console.log(uniqueUsers);
51
- * // Output: [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }]
52
- */
53
- export declare const uniqueArray: <T>(array: T[], keyExtractor?: (value: T, index: number, array: T[]) => string | number) => T[];
1
+ export { hasDuplicates, uniqueArray } from './array';
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Converts a hex color string to an RGB object.
3
+ *
4
+ * @param hex - The hex color string (e.g., "#ff5733" or "#f53").
5
+ * @returns An RGB object, or null if the hex string is invalid.
6
+ *
7
+ * @example
8
+ * hexToRgb("#ff5733") // { r: 255, g: 87, b: 51 }
9
+ * hexToRgb("#f53") // { r: 255, g: 85, b: 51 }
10
+ */
11
+ export declare const hexToRgb: (hex: string) => {
12
+ r: number;
13
+ g: number;
14
+ b: number;
15
+ } | null;
16
+ /**
17
+ * Converts RGB values to a hex color string.
18
+ *
19
+ * @param r - The red value (0-255).
20
+ * @param g - The green value (0-255).
21
+ * @param b - The blue value (0-255).
22
+ * @returns The hex color string.
23
+ *
24
+ * @example
25
+ * rgbToHex(255, 87, 51) // "#ff5733"
26
+ */
27
+ export declare const rgbToHex: (r: number, g: number, b: number) => string;
28
+ /**
29
+ * Lightens a hex color by a given percentage.
30
+ *
31
+ * @param hex - The hex color string.
32
+ * @param amount - The amount to lighten (0-1, where 1 is white).
33
+ * @returns The lightened hex color string.
34
+ *
35
+ * @example
36
+ * lighten("#000000", 0.5) // "#808080"
37
+ */
38
+ export declare const lighten: (hex: string, amount: number) => string;
39
+ /**
40
+ * Darkens a hex color by a given percentage.
41
+ *
42
+ * @param hex - The hex color string.
43
+ * @param amount - The amount to darken (0-1, where 1 is black).
44
+ * @returns The darkened hex color string.
45
+ *
46
+ * @example
47
+ * darken("#ffffff", 0.5) // "#808080"
48
+ */
49
+ export declare const darken: (hex: string, amount: number) => string;
@@ -1,6 +1,11 @@
1
+ /**
2
+ * Splits an input string into words, handling camelCase, PascalCase,
3
+ * snake_case, kebab-case, spaces, and mixed formats.
4
+ */
5
+ export declare const splitWords: (input: string) => string[];
1
6
  /**
2
7
  * Converts a string to camelCase.
3
- * Example: "hello world" → "helloWorld"
8
+ * Example: "hello world" → "helloWorld", "myVariableName" → "myVariableName"
4
9
  * @param input The input string.
5
10
  * @returns The camelCase version of the input.
6
11
  */
@@ -14,14 +19,14 @@ export declare const toCamelCase: (input: string) => string;
14
19
  export declare const toPascalCase: (input: string) => string;
15
20
  /**
16
21
  * Converts a string to snake_case.
17
- * Example: "hello world" → "hello_world"
22
+ * Example: "hello world" → "hello_world", "myVariableName" → "my_variable_name"
18
23
  * @param input The input string.
19
24
  * @returns The snake_case version of the input.
20
25
  */
21
26
  export declare const toSnakeCase: (input: string) => string;
22
27
  /**
23
28
  * Converts a string to kebab-case.
24
- * Example: "hello world" → "hello-world"
29
+ * Example: "hello world" → "hello-world", "myVariableName" → "my-variable-name"
25
30
  * @param input The input string.
26
31
  * @returns The kebab-case version of the input.
27
32
  */
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Generates a random alphanumeric ID.
3
+ *
4
+ * @param length - The length of the ID (default: 16).
5
+ * @returns A random alphanumeric string.
6
+ *
7
+ * @example
8
+ * generateId() // "a3bF9kL2mN7xP1qR"
9
+ * generateId(8) // "x4Hy9zKm"
10
+ */
11
+ export declare const generateId: (length?: number) => string;
12
+ /**
13
+ * Generates a simple non-cryptographic hash of a string (djb2 algorithm).
14
+ *
15
+ * @param str - The string to hash.
16
+ * @returns A numeric hash value.
17
+ *
18
+ * @example
19
+ * hash("hello") // 261238937
20
+ */
21
+ export declare const hash: (str: string) => number;
@@ -22,4 +22,4 @@ export declare const clone: <T>(data: T) => T;
22
22
  * - For objects, the function checks if they have the same keys and recursively compares their corresponding values.
23
23
  * - The function does not handle circular references and may result in a stack overflow for deeply nested structures.
24
24
  */
25
- export declare const isEqual: <T>(a: T, b: T) => boolean;
25
+ export declare const isEqual: <T>(a: T, b: T, seen?: WeakSet<object>) => boolean;
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Creates a debounced version of a function that delays invoking the function
3
+ * until after `ms` milliseconds have elapsed since the last time it was called.
4
+ *
5
+ * @param fn - The function to debounce.
6
+ * @param ms - The debounce delay in milliseconds.
7
+ * @returns The debounced function with a `cancel` method.
8
+ *
9
+ * @example
10
+ * const debouncedSave = debounce(save, 300)
11
+ * debouncedSave() // Only executes after 300ms of inactivity
12
+ * debouncedSave.cancel() // Cancel pending execution
13
+ */
14
+ export declare const debounce: <T extends (...args: any[]) => any>(fn: T, ms: number) => T & {
15
+ cancel(): void;
16
+ };
17
+ /**
18
+ * Creates a throttled version of a function that only invokes the function
19
+ * at most once per `ms` milliseconds.
20
+ *
21
+ * @param fn - The function to throttle.
22
+ * @param ms - The throttle interval in milliseconds.
23
+ * @returns The throttled function with a `cancel` method.
24
+ *
25
+ * @example
26
+ * const throttledScroll = throttle(onScroll, 100)
27
+ * window.addEventListener('scroll', throttledScroll)
28
+ * throttledScroll.cancel() // Cancel pending execution
29
+ */
30
+ export declare const throttle: <T extends (...args: any[]) => any>(fn: T, ms: number) => T & {
31
+ cancel(): void;
32
+ };
33
+ /**
34
+ * Creates a function that can only be called once. Subsequent calls return
35
+ * the result of the first invocation.
36
+ *
37
+ * @param fn - The function to restrict.
38
+ * @returns A function that only executes once.
39
+ *
40
+ * @example
41
+ * const initialize = once(() => console.log("init"))
42
+ * initialize() // logs "init"
43
+ * initialize() // does nothing
44
+ */
45
+ export declare const once: <T extends (...args: any[]) => any>(fn: T) => T;
46
+ /**
47
+ * A no-operation function that does nothing.
48
+ *
49
+ * @example
50
+ * const callback = options.onComplete || noop
51
+ */
52
+ export declare const noop: () => void;
@@ -1,13 +1,19 @@
1
- export * from './collection';
1
+ export * from './array';
2
+ export * from './color';
2
3
  export * from './constants';
3
4
  export * from './convertor';
5
+ export * from './crypto';
4
6
  export * from './data';
5
7
  export * from './errors';
8
+ export * from './function';
6
9
  export * from './math';
7
10
  export * from './media';
11
+ export * from './normalize';
12
+ export * from './object';
8
13
  export * from './promise';
9
14
  export * from './regex';
10
15
  export * from './size';
16
+ export * from './string';
11
17
  export * from './time';
12
18
  export * from './type';
13
19
  export * from './url';
@@ -33,3 +33,66 @@ export declare const clamp: (num: number, min: number, max: number) => number;
33
33
  * @returns A string with formatted number (e.g., "1,234,567").
34
34
  */
35
35
  export declare const formatNumber: (num: number) => string;
36
+ /**
37
+ * Sums an array of numbers.
38
+ *
39
+ * @param numbers - The numbers to sum.
40
+ * @returns The sum, or 0 for an empty array.
41
+ *
42
+ * @example
43
+ * sum([1, 2, 3]) // 6
44
+ */
45
+ export declare const sum: (numbers: number[]) => number;
46
+ /**
47
+ * Calculates the average of an array of numbers.
48
+ *
49
+ * @param numbers - The numbers to average.
50
+ * @returns The average, or 0 for an empty array.
51
+ *
52
+ * @example
53
+ * average([1, 2, 3, 4]) // 2.5
54
+ */
55
+ export declare const average: (numbers: number[]) => number;
56
+ /**
57
+ * Calculates the median of an array of numbers.
58
+ *
59
+ * @param numbers - The numbers to find the median of.
60
+ * @returns The median, or 0 for an empty array.
61
+ *
62
+ * @example
63
+ * median([1, 2, 3]) // 2
64
+ * median([1, 2, 3, 4]) // 2.5
65
+ */
66
+ export declare const median: (numbers: number[]) => number;
67
+ /**
68
+ * Returns the minimum value in an array of numbers.
69
+ *
70
+ * @param numbers - The numbers.
71
+ * @returns The minimum value, or Infinity for an empty array.
72
+ *
73
+ * @example
74
+ * min([3, 1, 4, 1, 5]) // 1
75
+ */
76
+ export declare const min: (numbers: number[]) => number;
77
+ /**
78
+ * Returns the maximum value in an array of numbers.
79
+ *
80
+ * @param numbers - The numbers.
81
+ * @returns The maximum value, or -Infinity for an empty array.
82
+ *
83
+ * @example
84
+ * max([3, 1, 4, 1, 5]) // 5
85
+ */
86
+ export declare const max: (numbers: number[]) => number;
87
+ /**
88
+ * Rounds a number to the specified number of decimal places.
89
+ *
90
+ * @param value - The number to round.
91
+ * @param decimals - The number of decimal places (default: 0).
92
+ * @returns The rounded number.
93
+ *
94
+ * @example
95
+ * round(1.2345, 2) // 1.23
96
+ * round(1.5) // 2
97
+ */
98
+ export declare const round: (value: number, decimals?: number) => number;
@@ -0,0 +1 @@
1
+ export declare const normalize: <T>(value: T | null | undefined) => T | null;
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Creates a new object with only the specified keys.
3
+ *
4
+ * @param obj - The source object.
5
+ * @param keys - The keys to pick.
6
+ * @returns A new object with only the specified keys.
7
+ *
8
+ * @example
9
+ * pick({ a: 1, b: 2, c: 3 }, ['a', 'c']) // { a: 1, c: 3 }
10
+ */
11
+ export declare const pick: <T extends Record<string, any>, K extends keyof T>(obj: T, keys: K[]) => Pick<T, K>;
12
+ /**
13
+ * Creates a new object without the specified keys.
14
+ *
15
+ * @param obj - The source object.
16
+ * @param keys - The keys to omit.
17
+ * @returns A new object without the specified keys.
18
+ *
19
+ * @example
20
+ * omit({ a: 1, b: 2, c: 3 }, ['b']) // { a: 1, c: 3 }
21
+ */
22
+ export declare const omit: <T extends Record<string, any>, K extends keyof T>(obj: T, keys: K[]) => Omit<T, K>;
23
+ /**
24
+ * Deep merges multiple objects together. Later values override earlier ones.
25
+ *
26
+ * @param objects - The objects to merge.
27
+ * @returns The merged object.
28
+ *
29
+ * @example
30
+ * merge({ a: 1, b: { c: 2 } }, { b: { d: 3 } }) // { a: 1, b: { c: 2, d: 3 } }
31
+ */
32
+ export declare const merge: <T extends Record<string, any>>(...objects: Partial<T>[]) => T;
33
+ /**
34
+ * Flattens a nested object into a single-level object with dot-separated keys.
35
+ *
36
+ * @param obj - The object to flatten.
37
+ * @param prefix - The prefix for keys (used internally for recursion).
38
+ * @returns A flat object.
39
+ *
40
+ * @example
41
+ * flattenObject({ a: { b: 1, c: { d: 2 } } }) // { 'a.b': 1, 'a.c.d': 2 }
42
+ */
43
+ export declare const flattenObject: (obj: Record<string, any>, prefix?: string) => Record<string, any>;
44
+ /**
45
+ * Unflattens a dot-separated flat object into a nested object.
46
+ *
47
+ * @param obj - The flat object to unflatten.
48
+ * @returns A nested object.
49
+ *
50
+ * @example
51
+ * unflattenObject({ 'a.b': 1, 'a.c.d': 2 }) // { a: { b: 1, c: { d: 2 } } }
52
+ */
53
+ export declare const unflattenObject: (obj: Record<string, any>) => Record<string, any>;
54
+ /**
55
+ * Gets the deep differences between two objects.
56
+ * Recursively compares nested objects and returns only the differing branches.
57
+ * For arrays, if they differ the entire new array is returned.
58
+ *
59
+ * @param a - The first object.
60
+ * @param b - The second object.
61
+ * @returns An object with the differing values from `b`.
62
+ *
63
+ * @example
64
+ * diff({ a: 1, b: { c: 2, d: 3 } }, { a: 1, b: { c: 5, d: 3 } })
65
+ * // { b: { c: 5 } }
66
+ *
67
+ * diff({ tags: [1, 2] }, { tags: [1, 3] })
68
+ * // { tags: [1, 3] }
69
+ */
70
+ export declare const diff: <T extends Record<string, any>>(a: T, b: T) => Partial<T>;
@@ -5,3 +5,33 @@
5
5
  * @returns A promise that resolves after the delay.
6
6
  */
7
7
  export declare const sleep: (ms: number) => Promise<void>;
8
+ /**
9
+ * Retries a function up to a specified number of times with optional exponential backoff.
10
+ *
11
+ * @param fn - The async function to retry.
12
+ * @param options - Retry options.
13
+ * @param options.retries - The maximum number of retries (default: 3).
14
+ * @param options.delay - The delay in milliseconds between retries (default: 1000).
15
+ * @param options.backoff - Whether to use exponential backoff (default: false).
16
+ * @returns The result of the function.
17
+ *
18
+ * @example
19
+ * const data = await retry(() => fetch('/api/data'), { retries: 3, delay: 1000, backoff: true })
20
+ */
21
+ export declare const retry: <T>(fn: () => Promise<T>, options?: {
22
+ retries?: number;
23
+ delay?: number;
24
+ backoff?: boolean;
25
+ }) => Promise<T>;
26
+ /**
27
+ * Wraps a promise with a timeout. Rejects if the promise doesn't resolve within the specified time.
28
+ *
29
+ * @param promise - The promise to wrap.
30
+ * @param ms - The timeout in milliseconds.
31
+ * @param message - Optional custom error message.
32
+ * @returns The result of the promise.
33
+ *
34
+ * @example
35
+ * const data = await timeout(fetch('/api/data'), 5000, 'Request timed out')
36
+ */
37
+ export declare const timeout: <T>(promise: Promise<T>, ms: number, message?: string) => Promise<T>;