Skip to content

Commit

Permalink
fix(collection): reordered overloads of groupBy function
Browse files Browse the repository at this point in the history
Reordered the overloads of the `groupBy` function for better type inference and usability. The change swaps the positions of the overloads to prioritize the more common use case where the `groupBy` function is used with an iterator function over the version that groups by a property path. This adjustment ensures that TypeScript correctly infers the types in scenarios where the distinction between the use cases is subtle, enhancing developer experience when working with the `groupBy` function.
  • Loading branch information
shorwood committed Apr 25, 2024
1 parent 0505880 commit 2461893
Showing 1 changed file with 10 additions and 9 deletions.
19 changes: 10 additions & 9 deletions packages/collection/groupBy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ type GroupedByIterator<T, R extends PropertyKey> =
: { [K in keyof T as R]: Array<T[K]> } extends infer U ? { -readonly [K in keyof U]: U[K] } : never

/**
* Groups a collection by the value of a property at a given path.
* Groups a collection by the result of an iterator function.
*
* @param collection The collection to group.
* @param path The path to the property to group by.
* @param iterator The iterator function to determine the group of each item.
* @returns An object where the keys are the groups and the values are the items in each group.
* @example
* // Declare a collection.
Expand All @@ -28,18 +28,18 @@ type GroupedByIterator<T, R extends PropertyKey> =
* ]
*
* // Group the collection by the value of the `group` property.
* groupBy(collection, 'group')
* groupBy(collection, item => item.group)
* // {
* // a: [{ id: 1, group: 'a' }, { id: 2, group: 'a' }],
* // b: [{ id: 3, group: 'b' }, { id: 4, group: 'b' }],
* // }
*/
export function groupBy<T, P extends IteratorPath<T>>(collection: T, path: MaybeLiteral<P>): GroupedByPath<T, P>
export function groupBy<T, R extends PropertyKey>(collection: T, iterator: IteratorFunction<T, R>): GroupedByIterator<T, R>
/**
* Groups a collection by the result of an iterator function.
* Groups a collection by the value of a property at a given path.
*
* @param collection The collection to group.
* @param iterator The iterator function to determine the group of each item.
* @param path The path to the property to group by.
* @returns An object where the keys are the groups and the values are the items in each group.
* @example
* // Declare a collection.
Expand All @@ -51,14 +51,15 @@ export function groupBy<T, P extends IteratorPath<T>>(collection: T, path: Maybe
* ]
*
* // Group the collection by the value of the `group` property.
* groupBy(collection, item => item.group)
* groupBy(collection, 'group')
* // {
* // a: [{ id: 1, group: 'a' }, { id: 2, group: 'a' }],
* // b: [{ id: 3, group: 'b' }, { id: 4, group: 'b' }],
* // }
*/
export function groupBy<T, R extends PropertyKey>(collection: T, iterator: IteratorFunction<T, R>): GroupedByIterator<T, R>
export function groupBy(collection: object, iteratorOrPath: IteratorFunction<unknown, PropertyKey> | string) {
export function groupBy<T, P extends IteratorPath<T>>(collection: T, path: MaybeLiteral<P>): GroupedByPath<T, P>
export function groupBy(collection: object, iteratorOrPath: IteratorFunction<unknown, PropertyKey> | string): unknown
export function groupBy(collection: object, iteratorOrPath: IteratorFunction<unknown, PropertyKey> | string): unknown {

// --- If iterator is a string, cast as nested getter function.
const iterator = typeof iteratorOrPath === 'function'
Expand Down

0 comments on commit 2461893

Please sign in to comment.