Skip to content

Commit 8a3711e

Browse files
Copilotcoder13
andcommitted
Fix all implicit any errors in utils.ts - comprehensive type annotations
Co-authored-by: coder13 <881394+coder13@users.noreply.github.com>
1 parent 860216f commit 8a3711e

File tree

1 file changed

+49
-86
lines changed

1 file changed

+49
-86
lines changed

src/lib/utils.ts

Lines changed: 49 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -2,183 +2,146 @@ import { AttemptResult, EventId, RankingType, formatCentiseconds } from '@wca/he
22

33
/**
44
* Returns a copy of the object with the value at the specified path transformed by the update function.
5-
*
6-
* @param {Object} object
7-
* @param {Array} propertyChain
8-
* @param {Function} updater
9-
* @returns {Object}
105
*/
11-
export const updateIn = (object, [property, ...properyChain]: string[], updater) =>
6+
export const updateIn = <T>(object: T, [property, ...properyChain]: string[], updater: (value: unknown) => unknown): T =>
127
properyChain.length === 0
13-
? { ...object, [property]: updater(object[property]) }
8+
? { ...object, [property]: updater((object as Record<string, unknown>)[property]) }
149
: {
1510
...object,
16-
[property]: updateIn(object[property], properyChain, updater),
11+
[property]: updateIn((object as Record<string, unknown>)[property], properyChain, updater),
1712
};
1813

1914
/**
2015
* Returns a copy of the object with the value at the specified path set to the given one.
21-
*
22-
* @param {Object} object
23-
* @param {Array} propertyChain
24-
* @param {*} value
25-
* @returns {Object}
2616
*/
27-
export const setIn = (object, properyChain, value) => updateIn(object, properyChain, () => value);
17+
export const setIn = <T>(object: T, properyChain: string[], value: unknown): T =>
18+
updateIn(object, properyChain, () => value);
2819

2920
/**
3021
* Returns a copy of the object with the value at the specified path merged with the given one.
31-
*
32-
* @param {Object} object
33-
* @param {Array} propertyChain
34-
* @param {Object} newValue
35-
* @returns {Object}
3622
*/
37-
export const mergeIn = (object, properyChain, newValue) =>
23+
export const mergeIn = <T>(object: T, properyChain: string[], newValue: Record<string, unknown>): T =>
3824
updateIn(object, properyChain, (currentValue) => ({
39-
...currentValue,
25+
...(currentValue as Record<string, unknown>),
4026
...newValue,
4127
}));
4228

4329
/**
4430
* Returns a copy of the object with the array at the specified path mapped with the given function.
45-
*
46-
* @param {Object} object
47-
* @param {Array<string>} propertyChain
48-
* @param {Object} mapper
49-
* @returns {Object}
5031
*/
51-
export const mapIn = (object, properyChain, mapper) =>
52-
updateIn(object, properyChain, (array) => array && array.map(mapper));
32+
export const mapIn = <T>(object: T, properyChain: string[], mapper: (item: unknown) => unknown): T =>
33+
updateIn(object, properyChain, (array) => (array as unknown[])?.map(mapper));
5334

5435
/**
5536
* Returns object's value at the specified path or the default value if it doesn't exist.
56-
*
57-
* @param {Object} object
58-
* @param {Array} propertyChain
59-
* @param {*} defaultValue
60-
* @returns {*}
6137
*/
62-
export const getIn = (object, [property, ...propertyChain]: string[], defaultValue = null) =>
38+
export const getIn = (object: Record<string, unknown> | null | undefined, [property, ...propertyChain]: string[], defaultValue: unknown = null): unknown =>
6339
object
6440
? propertyChain.length === 0
6541
? object.hasOwnProperty(property)
6642
? object[property]
6743
: defaultValue
68-
: getIn(object[property], propertyChain, defaultValue)
44+
: getIn(object[property] as Record<string, unknown>, propertyChain, defaultValue)
6945
: defaultValue;
7046

7147
/**
7248
* Checks if the given value is an object.
73-
*
74-
* @param {*} value
75-
* @returns {boolean}
7649
*/
77-
const isObject = (obj) => obj === Object(obj);
50+
const isObject = (obj: unknown): obj is Record<string, unknown> => obj === Object(obj);
7851

7952
/**
8053
* When given an object, deeply checks if it doesn't contain null values.
8154
* Otherwise, checks if the given value is not null.
82-
*
83-
* @param {*} value
84-
* @returns {boolean}
8555
*/
86-
export const isPresentDeep = (value) =>
56+
export const isPresentDeep = (value: unknown): boolean =>
8757
isObject(value) ? Object.values(value).every(isPresentDeep) : value != null;
8858

8959
/**
9060
* Pluralizes a word according to the given number.
9161
* When no plural form given, uses singular form with an 's' appended.
92-
*
93-
* @param {number} count
94-
* @param {string} singular
95-
* @param {string} plural
96-
* @returns {string}
9762
*/
98-
export const pluralize = (count, singular, plural) =>
63+
export const pluralize = (count: number, singular: string, plural?: string): string =>
9964
`${count} ${count === 1 ? singular : plural || singular + 's'}`;
10065

10166
/**
10267
* Pluralizes a word according to the given number.
10368
* When no plural form given, uses singular form with an 's' appended.
104-
*
105-
* @param {number} count
106-
* @param {string} singular
107-
* @param {string} plural
108-
* @returns {string}
10969
*/
110-
export const pluralizeWord = (count, singular, plural) =>
70+
export const pluralizeWord = (count: number, singular: string, plural?: string): string =>
11171
`${count === 1 ? singular : plural || singular + 's'}`;
11272

11373
/**
11474
* Returns a new array with items summing up to 1, preserving elements proportionality.
11575
* When the given array is empty, returns an empty array.
116-
*
117-
* @param {Array} arr
118-
* @returns {Array}
11976
*/
120-
export const scaleToOne = (arr) => {
77+
export const scaleToOne = (arr: number[]): number[] => {
12178
if (arr.length === 0) return [];
12279
const arrSum = sum(arr);
12380
return arr.map((x) => (arrSum !== 0 ? x / arrSum : 1 / arr.length));
12481
};
12582

12683
/**
12784
* Applies the given function to the elements and returns the first truthy value of these calls.
128-
*
129-
* @param {Array} arr
130-
* @returns {*}
13185
*/
132-
export const firstResult = (arr, fn) => arr.reduce((result, x) => result || fn(x), null);
86+
export const firstResult = <T, R>(arr: T[], fn: (item: T) => R): R | null =>
87+
arr.reduce((result: R | null, x) => result || fn(x), null);
13388

134-
export const flatMap = (arr, fn) => arr.reduce((xs, x) => xs.concat(fn(x)), []);
89+
export const flatMap = <T, R>(arr: T[], fn: (item: T) => R[]): R[] =>
90+
arr.reduce((xs: R[], x) => xs.concat(fn(x)), []);
13591

136-
export const flatten = (arr) => arr.reduce((xs, x) => xs.concat(x), []);
92+
export const flatten = <T>(arr: T[][]): T[] => arr.reduce((xs, x) => xs.concat(x), []);
13793

13894
/**
139-
*
140-
* @param {Array} arr - Array of elements
141-
* @param {*} fn - returns a value to group by
142-
* @returns
95+
* Groups array elements by a given function
14396
*/
144-
export const groupBy = (arr, fn) =>
145-
arr.reduce((obj, x) => updateIn(obj, [fn(x)], (xs) => (xs || []).concat(x)), {});
97+
export const groupBy = <T, K extends string | number>(arr: T[], fn: (item: T) => K): Record<K, T[]> =>
98+
arr.reduce((obj, x) => updateIn(obj, [String(fn(x))], (xs) => ((xs as T[]) || []).concat(x)), {} as Record<K, T[]>);
14699

147-
export const zip = (...arrs) =>
100+
export const zip = <T>(...arrs: T[][]): T[][] =>
148101
arrs.length === 0 ? [] : arrs[0].map((_, i) => arrs.map((arr) => arr[i]));
149102

150-
export const findLast = (arr, predicate) =>
103+
export const findLast = <T>(arr: T[], predicate: (item: T) => boolean): T | undefined =>
151104
arr.reduceRight(
152105
(found, x) => (found !== undefined ? found : predicate(x) ? x : undefined),
153-
undefined
106+
undefined as T | undefined
154107
);
155108

156-
export const intersection = (xs, ys) => xs.filter((x) => ys.includes(x));
109+
export const intersection = <T>(xs: T[], ys: T[]): T[] => xs.filter((x) => ys.includes(x));
157110

158-
export const difference = (xs, ys) => xs.filter((x) => !ys.includes(x));
111+
export const difference = <T>(xs: T[], ys: T[]): T[] => xs.filter((x) => !ys.includes(x));
159112

160-
export const partition = (xs, fn) => [xs.filter(fn), xs.filter((x) => !fn(x))];
113+
export const partition = <T>(xs: T[], fn: (item: T) => boolean): [T[], T[]] =>
114+
[xs.filter(fn), xs.filter((x) => !fn(x))];
161115

162-
const sortCompare = (x, y) => (x < y ? -1 : x > y ? 1 : 0);
116+
const sortCompare = (x: unknown, y: unknown): number => (x < y ? -1 : x > y ? 1 : 0);
163117

164-
export const sortBy = (arr, fn) => arr.slice().sort((x, y) => sortCompare(fn(x), fn(y)));
118+
export const sortBy = <T>(arr: T[], fn: (item: T) => unknown): T[] =>
119+
arr.slice().sort((x, y) => sortCompare(fn(x), fn(y)));
165120

166-
export const sortByArray = (arr, fn) => {
121+
export const sortByArray = <T>(arr: T[], fn: (item: T) => unknown[]): T[] => {
167122
const values = new Map(arr.map((x) => [x, fn(x)])); /* Compute every value once. */
123+
const firstResult = <R>(pairs: unknown[][], fn: (pair: [unknown, unknown]) => R | 0): R | 0 => {
124+
for (const pair of pairs) {
125+
const result = fn(pair as [unknown, unknown]);
126+
if (result !== 0) return result;
127+
}
128+
return 0;
129+
};
168130
return arr
169131
.slice()
170-
.sort((x, y) => firstResult(zip(values.get(x), values.get(y)), ([a, b]) => sortCompare(a, b)));
132+
.sort((x, y) => firstResult(zip(values.get(x) as unknown[], values.get(y) as unknown[]), ([a, b]) => sortCompare(a, b)));
171133
};
172134

173-
export const chunk = (arr, size) =>
135+
export const chunk = <T>(arr: T[], size: number): T[][] =>
174136
arr.length <= size ? [arr] : [arr.slice(0, size), ...chunk(arr.slice(size), size)];
175137

176-
export const times = (n, fn) => Array.from({ length: n }, (_, index) => fn(index));
138+
export const times = <T>(n: number, fn: (index: number) => T): T[] =>
139+
Array.from({ length: n }, (_, index) => fn(index));
177140

178141
export const uniq = <T>(arr: T[]): T[] => [...new Set(arr)];
179142

180-
export const pick = (obj, keys) =>
181-
keys.reduce((newObj, key) => ({ ...newObj, [key]: obj[key] }), {});
143+
export const pick = <T extends Record<string, unknown>>(obj: T, keys: (keyof T)[]): Partial<T> =>
144+
keys.reduce((newObj, key) => ({ ...newObj, [key]: obj[key] }), {} as Partial<T>);
182145

183146
export const omit = <T extends object, K extends keyof T>(obj: T, ...keys: K[]): Omit<T, K> => {
184147
const _ = { ...obj }
@@ -197,7 +160,7 @@ export const addMilliseconds = (isoString: string, milliseconds: number) =>
197160
export const isoTimeDiff = (first: string, second: string) =>
198161
Math.abs(new Date(first).getTime() - new Date(second).getTime());
199162

200-
export const shortTime = (isoString, timeZone = 'UTC') =>
163+
export const shortTime = (isoString: string, timeZone = 'UTC') =>
201164
new Date(isoString).toLocaleTimeString('en-US', {
202165
timeZone,
203166
hour: 'numeric',

0 commit comments

Comments
 (0)