UNPKG

remeda

Version:

A utility library for JavaScript and Typescript.

86 lines (85 loc) 4.55 kB
import { IterableContainer } from "./IterableContainer-JENOIFLG.cjs"; import { TupleParts } from "./TupleParts-BV9kUr1M.cjs"; import { BoundedPartial } from "./BoundedPartial-Dk-WxpZ7.cjs"; import { FilteredArray } from "./FilteredArray-BxwgjOR6.cjs"; import { ArrayRequiredPrefix } from "./ArrayRequiredPrefix-64UMblqq.cjs"; import { AllUnionFields, And, ConditionalKeys, IfNever, Merge } from "type-fest"; //#region src/groupByProp.d.ts type GroupByProp<T extends IterableContainer, Prop extends GroupableProps<T>> = T extends unknown ? FixEmptyObject<EnsureValuesAreNonEmpty<{ [Value in AllPropValues<T, Prop>]: FilteredArray<T, Record<Prop, Value>> }>> : never; type GroupableProps<T extends IterableContainer> = ConditionalKeys<ItemsSuperObject<T>, PropertyKey | undefined>; type AllPropValues<T extends IterableContainer, Prop extends GroupableProps<T>> = Extract<ItemsSuperObject<T>[Prop], PropertyKey>; type ItemsSuperObject<T extends IterableContainer> = AllUnionFields<Exclude<T[number], undefined>>; type FixEmptyObject<T> = IfNever<keyof T, Record<PropertyKey, never>, T>; type EnsureValuesAreNonEmpty<T extends Record<PropertyKey, IterableContainer>> = Merge<T, BoundedPartial<{ [P in keyof T as IsPossiblyEmpty<T[P]> extends true ? P : never]: ArrayRequiredPrefix<T[P], 1> }>>; type IsPossiblyEmpty<T extends IterableContainer> = And<IsEmpty<TupleParts<T>["required"]>, IsEmpty<TupleParts<T>["suffix"]>>; type IsEmpty<T> = T extends readonly [] ? true : false; /** * Groups the elements of an array of objects based on the values of a * specified property of those objects. The result would contain a property for * each unique value of the specific property, with it's value being the input * array filtered to only items that have that property set to that value. * For any object where the property is missing, or if it's value is * `undefined` the item would be filtered out. * * The grouping property is enforced at the type level to exist in at least one * item and to never have a value that cannot be used as an object key (e.g. it * must be `PropertyKey | undefined`). * * The resulting arrays are filtered with the prop and it's value as a * type-guard, effectively narrowing the items in each output arrays. This * means that when the grouping property is the discriminator of a * discriminated union type each output array would contain just the subtype for * that value. * * If you need more control over the grouping you should use `groupBy` instead. * * @param data - The items to group. * @param prop - The property name to group by. * @signature * R.groupByProp(data, prop) * @example * const result = R.groupByProp( * // ^? { cat: [{ a: 'cat' }], dog: [{ a: 'dog' }] } * [{ a: 'cat' }, { a: 'dog' }] as const, * 'a', * ); * @dataFirst * @category Array */ declare function groupByProp<T extends IterableContainer, Prop extends GroupableProps<T>>(data: T, prop: Prop): GroupByProp<T, Prop>; /** * Groups the elements of an array of objects based on the values of a * specified property of those objects. The result would contain a property for * each unique value of the specific property, with it's value being the input * array filtered to only items that have that property set to that value. * For any object where the property is missing, or if it's value is * `undefined` the item would be filtered out. * * The grouping property is enforced at the type level to exist in at least one * item and to never have a value that cannot be used as an object key (e.g. it * must be `PropertyKey | undefined`). * * The resulting arrays are filtered with the prop and it's value as a * type-guard, effectively narrowing the items in each output arrays. This * means that when the grouping property is the discriminator of a * discriminated union type each output array would contain just the subtype for * that value. * * If you need more control over the grouping you should use `groupBy` instead. * * @param prop - The property name to group by. * @signature * R.groupByProp(prop)(data); * @example * const result = R.pipe( * // ^? { cat: [{ a: 'cat' }], dog: [{ a: 'dog' }] } * [{ a: 'cat' }, { a: 'dog' }] as const, * R.groupByProp('a'), * ); * @dataLast * @category Array */ declare function groupByProp<T extends IterableContainer, Prop extends GroupableProps<T>>(prop: Prop): (data: T) => GroupByProp<T, Prop>; //#endregion export { groupByProp }; //# sourceMappingURL=groupByProp-CF4nX1Qm.d.cts.map