У меня есть приложение Angular 8 / TS, и я хотел бы добавить функцию .groupBy()
в прототип Array. Я прочитал в TypeScript этот параметр , в котором говорится, что вы просто добавляете this: <Type>
в качестве ложного первого параметра к вашему аргументу.
Это прекрасно работает внутри метод, как я определяю его для прототипа, но где бы я не вызывал метод, мой массив возвращается к типу any
.
Так что, я думаю, моя проблема в том, что я Я использую массив (это generi c), и моя функция принимает параметры c, например:
if(!Array.prototype.groupBy) {
Array.prototype.groupBy = function<T, TKey, TResult>(
this: T[], // here's the magical "this" parameter
keySelector: (item: T) => TKey,
itemSelector: (item: T) => TResult
): Group<TResult, TKey>[] {
У меня есть тестовый метод в том же файле, который вызывает мой новый метод :
function test(): void {
let arr: number[] = [ 11, 29, 32, 33, 10, 55 ];
let groupByTens = arr.groupBy(
i => i / 10, // here, "i" is "unknown" which generates a compile error
i => i.toString());
}
Если я явно при вызове arr.groupBy<number, number, string>(..)
, то это работает, найти, но я не хочу явно указывать типы generi c. Как я могу написать свой «метод расширения» таким образом, чтобы мне не пришлось явно указывать тип c generic?
Спасибо!
И для полноты, вот моя полная функция groupBy:
if(!Array.prototype.groupBy) {
Array.prototype.groupBy = function<T, TKey, TResult>(
this: T[],
keySelector: (item: T) => TKey,
itemSelector: (item: T) => TResult
): Group<TResult, TKey>[] {
let groupDict: any = {};
// HERE, if I provide the "this parameter", then "this" is an Array<T>. If I don't,
// then "this" is an "any". So the "this parameter" is working just fine inside the
// function declaration.
this.forEach((item: T) => {
let groupKey = keySelector(item);
let group = groupDict[groupKey];
if (!group) {
group = new Group<TResult, TKey>(groupKey);
groupDict[groupKey] = group;
}
group.members.push(itemSelector(item))
});
return Object.keys(groupDict)
.map(key => <Group<TResult, TKey>>groupDict[key]);
}
}