TypeScript new Array.prototype Generi c Функция с параметром 'this' - PullRequest
0 голосов
/ 22 февраля 2020

У меня есть приложение 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]);
    }
}
...