Изучаю TypeScript, и появилась необходимость типизировать одну из функций:
const groupBy = (collection, extractor) => collection.reduce((accumulator, entry) => {
const key = extractor(entry);
if (!accumulator.has(key)) {
accumulator.set(key, []);
}
accumulator.get(key).push(entry);
return accumulator;
}, new Map());
На TypeScript переписал следующим образом:
type Extractor<T> = (entry: T) => T[keyof T];
const groupBy = <T>(
collection: T[],
mapper: Extractor<T>
): Map<ReturnType<Extractor<T>>, T[]> => collection.reduce((accumulator, entry) => {
const key = mapper(entry);
if (!accumulator.has(key)) {
accumulator.set(key, []);
}
accumulator.get(key).push(entry);
return accumulator;
}, new Map());
Но при использовании появилась проблема - как правильно использовать возвращаемый тип (
ReturnType
) функции, которая была передана в функцию
groupBy
. Пример:
interface IRole {
name: string;
power: number;
}
interface IUser {
name: string;
role: IRole;
}
const users: IUser[] = [
{
name: 'Andry',
role: {
name: 'admin',
power: 127
}
},
{
name: 'Alex',
role: {
name: 'admin',
power: 127
}
},
{
name: 'John',
role: {
name: 'guest',
power: 1
}
}
];
type Extractor<T> = (entry: T) => T[keyof T];
const groupBy = <T>(
collection: T[],
mapper: Extractor<T>
): Map<ReturnType<Extractor<T>>, T[]> => collection.reduce((accumulator, entry) => {
const key = mapper(entry);
if (!accumulator.has(key)) {
accumulator.set(key, []);
}
accumulator.get(key).push(entry);
return accumulator;
}, new Map());
const groupedUsers = groupBy(users, user => user.name[0].toUpperCase()); // Map<string | IRole, IUser[]>
Как необходимо исправить тип аргумента
extractor
, чтобы использовать тип
string
, возвращаемый данной функцией?