Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to enable Object.groupBy() in TypeScript and Node.js

I am running on Node.js v18.17.1 and TypeScript v5.

I heard about the new JavaScript method Object.groupBy().

const inventory = [
  { name: "asparagus", type: "vegetables", quantity: 5 },
  { name: "bananas", type: "fruit", quantity: 0 },
  { name: "goat", type: "meat", quantity: 23 },
  { name: "cherries", type: "fruit", quantity: 5 },
  { name: "fish", type: "meat", quantity: 22 },
];

const result = Object.groupBy(inventory, ({ type }) => type);
console.log(result)

When I write in my code Object.groupBy(), I get the following TypeScript error:

Property 'groupBy' does not exist on type 'ObjectConstructor'.ts(2339)

I have the following TypeScript configuration:

 "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    // ... etc

How can I enable Object.groupBy() so that I can use it in my code?

like image 804
Islam Y- Avatar asked Sep 08 '25 18:09

Islam Y-


2 Answers

Here is the PR to enable it: https://github.com/microsoft/TypeScript/pull/56805. It's in state Open at the moment. Hopefully will be merged soon.

Before it merged you can use a workaround adding these extension interfaces in your project:

/// {projectSrcRoot}/groupBy.d.ts

interface ObjectConstructor {
    /**
     * Groups members of an iterable according to the return value of the passed callback.
     * @param items An iterable.
     * @param keySelector A callback which will be invoked for each item in items.
     */
    groupBy<K extends PropertyKey, T>(
        items: Iterable<T>,
        keySelector: (item: T, index: number) => K,
    ): Partial<Record<K, T[]>>;
}

interface MapConstructor {
    /**
     * Groups members of an iterable according to the return value of the passed callback.
     * @param items An iterable.
     * @param keySelector A callback which will be invoked for each item in items.
     */
    groupBy<K, T>(
        items: Iterable<T>,
        keySelector: (item: T, index: number) => K,
    ): Map<K, T[]>;
}

const basic = Object.groupBy([0, 2, 8], x => x < 5 ? 'small' : 'large');
like image 50
Philipp Munin Avatar answered Sep 10 '25 06:09

Philipp Munin


(as of today)

I've tried with NodeJS 21v (v21.6.1) and Typescript "5.4.0-beta"

tsconfig.json

 "compilerOptions": {
    "target": "ESNext",
    "module": "ESNext",
    ...
    "skipLibCheck": true // you might need it
  }

.vscode/settings.json (if using vscode) this is to specify the Typescript version of current workspaces

{
    "typescript.tsdk": "node_modules/typescript/lib"
    ...
}

example:

const people = [
  { name: "Alice", age: 25 },
  { name: "Bob", age: 42 },
  { name: "Charlie", age: 60 },
  { name: "David", age: 30 },
  // ... more people
];

// Group people by age range
const ageGroups = Object.groupBy(people, (person) => {
  if (person.age < 30) return "young";
  else if (person.age >= 30 && person.age < 60) return "adult";
  else return "senior";
});

console.log(ageGroups)

source: Announcing TypeScript 5.4 Beta

like image 33
Roberto A. Batty Avatar answered Sep 10 '25 06:09

Roberto A. Batty