3

Given all the answers already out there we tried to create a groupBy arrow function that doesn't complain about TypeScript errors. with guidance from this answer and this one we already have this working code:

const groupBy = <TItem>(
  items: TItem[],
  key: string
): { [key: string]: TItem[] } =>
  items.reduce(
    (result, item) => ({
      ...result,
      [item[key]]: [...(result[item[key]] || []), item],
    }),
    {}
  )

However, it still complains: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'unknown'.
No index signature with a parameter of type 'string' was found on type 'unknown'.

It is indeed possible that the used key is empty/blank. So TypeScript is not wrong here. So in that case it should simply use a placeholder value like NA or something.

What is the correct way to create a reusable error free typescript version for this groupBy function?

DarkLite1
  • 13,637
  • 40
  • 117
  • 214

1 Answers1

5

Use some generics to lower down the key type and force the object to contain the key:

type ObjectKey = string | number | symbol;

const groupBy = <K extends ObjectKey, TItem extends Record<K, ObjectKey>>(
  items: TItem[],
  key: K
): Record<ObjectKey, TItem[]> =>
  items.reduce(
    (result, item) => ({
      ...result,
      [item[key]]: [...(result[item[key]] || []), item],
    }),
    {} as Record<ObjectKey, TItem[]>
  );

Playground link

Aplet123
  • 33,825
  • 1
  • 29
  • 55
  • Thank you very much! I couldn't figure this out myself. Works like a charm as long as the `ObjectKey` is not null, but that's easily fixed. – DarkLite1 Dec 08 '20 at 07:29
  • @henroper ...you don't. The goal is to group the objects by a key, not to change them by removing a key. – Aplet123 Jul 29 '21 at 21:03
  • @henroper First of all, it'd be nice if you used a permanent service like pastebin instead of a 24 hour service like privatebin, but also, that's exactly my point. The goal is to group objects by a key, not to remove the grouped key from the objects. – Aplet123 Jul 30 '21 at 20:43