Extend array prototype correctly

Viewed 35

I have a groupBy method with which I would like to extend Array.

const groupBy = <T>(array: T[], predicate: (value: T, index: number, array: T[]) => string) =>
  array.reduce((acc, value, index, array) => {
    (acc[predicate(value, index, array)] ||= []).push(value);
    return acc;
  }, {} as { [key: string]: T[] });

I found the method here, and I'm trying to enable my arrays to operate like const groupItems = myItems.groupBy(item => item.key).

I have the basic extension code setup, along with a distinct method already applied. How can I take this groupBy method, and correctly apply it as an extension to be able to use it like const groupItems = myItems.groupBy(item => item.key)?

Existing extension code:

export { };
declare global {
    interface Array<T> {
        distinct(): Array<T>;
    }
}

if (!Array.prototype.distinct) {
    Array.prototype.distinct = function <T>(): T[] {
        const stringifiedItems = this.map((item) => JSON.stringify(item));
        const set = new Set(stringifiedItems);
        return Array.from(set).map((item) => JSON.parse(item));
    };
}
1 Answers

I was able to do this with this code:

export { };
declare global {
    interface Array<T> {
        distinct(): Array<T>;
        // Add the interface declaration
        groupBy(predicate: (value: T, index: number, array: T[]) => string): { [key: string]: T[] }
    }
}

if (!Array.prototype.distinct) {
    Array.prototype.distinct = function <T>(): T[] {
        const stringifiedItems = this.map((item) => JSON.stringify(item));
        const set = new Set(stringifiedItems);
        return Array.from(set).map((item) => JSON.parse(item));
    };
}

// Add it to the prototype
if (!Array.prototype.groupBy) {
    Array.prototype.groupBy = function <T>(predicate: (value: T, index: number, array: T[]) => string) {
        return this.reduce((acc, value, index, array) => {
            (acc[predicate(value, index, array)] ||= []).push(value);
            return acc;
        }, {} as { [key: string]: T[] });
    }
}

Related