remeda
Version:
A utility library for JavaScript and Typescript.
86 lines (85 loc) • 4.55 kB
text/typescript
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