Skip to content

Instantly share code, notes, and snippets.

@gvergnaud
Last active January 8, 2023 18:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gvergnaud/5a1243b445162637f92c6bf4961c9aa4 to your computer and use it in GitHub Desktop.
Save gvergnaud/5a1243b445162637f92c6bf4961c9aa4 to your computer and use it in GitHub Desktop.
import type { Equal, Expect } from '@type-challenges/utils'
type Assign<A, B> = {
[K in keyof A | keyof B]: K extends keyof B
? B[K]
: K extends keyof A
? A[K]
: never;
}
type As<a, b> = a extends b ? a : never
type GroupBy<xs, key, acc = {}> =
xs extends [infer first, ...infer rest]
? key extends keyof first
? GroupBy<
rest,
key,
Assign<acc, {
[K in As<first[key], PropertyKey>]: [
...(first[key] extends keyof acc ? As<acc[first[key]], any[]> : []),
first
]
}>
>
: GroupBy<rest, key, acc>
: acc
type res1 = GroupBy<[[1,2,3], [1,3,4], [2,3,4]], 0>
type res2 = GroupBy<[
{ role: 'admin', name: 'A' },
{ role: 'admin', name: 'B' },
{ role: 'user', name: 'C' },
{ role: 'user', name: 'D' },
{ role: 'user', name: 'E' }
], 'role'>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment