Back to notebook
June 2, 20251 min read

A try at type-safe groupBy function in TypeScript

In this post, I discuss how to integrate Prettier with ESLint using the eslint-config-prettier plugin, including tips and gotchas.

Why bother

Running Prettier and ESLint side by side without the config plugin means their formatting rules fight each other on every save.

The fix

function groupBy<T, K extends PropertyKey>(items: T[], key: (item: T) => K): Record<K, T[]> {
  return items.reduce((acc, item) => {
    const group = key(item);
    (acc[group] ??= []).push(item);
    return acc;
  }, {} as Record<K, T[]>);
}

A few gotchas worth calling out:

  • Type inference breaks down once the key function returns a union wider than the actual keys present.
  • Record<K, T[]> assumes every possible K value shows up, which isn't guaranteed at runtime.
  • A Partial<Record<K, T[]>> return type is more honest, at the cost of forcing callers to handle undefined.
Paziresh.me|Ali Reza Paziresh