OliverRadini
OliverRadini

Reputation: 6467

Grouping objects in an array by a given key

If I wanted to group an array of objects according to the values on a given key, I might have code such as:

export const potentialProp = <T extends {}>(key: PropertyKey, x: T) => Maybe.fromUndefined(
    x[key],
);

export const groupByKey = <T, K extends keyof T & PropertyKey>(key: K, x: T[]) => x
    .reduce(
        (p, c) => {
            const thisKey = c[key];

            return {
                ...p,
                [thisKey]: potentialProp(thisKey, p) // Type 'T[string]' is not assignable to type 'symbol'
                    .map(currentGroup => [...currentGroup, c])
                    .getOrElse([c]),
            };
        },
        {},
    );

This all works fine, expect that when I try and use [thisKey] to define a computed property, I get the error:

Type 'T[string]' is not assignable to type 'symbol'

I can understand why this is happening; T[K] might be anything, and there's nothing to guarantee that the type of value at the key can be used as a key on a new object.

To get around this, I've tried the following:

if (
    keyType !== 'string'
        && keyType !== 'number'
        && keyType !== 'symbol'
) {
    return {};
}

In the hope that this would make the type sufficiently narrow to be able to be used as a computed property, but I was unfortunately mistaken in that.

Is it possible to get this to work in Typescript?

Upvotes: 0

Views: 62

Answers (1)

GideonMax
GideonMax

Reputation: 594

explicitly casting T[K] to type PropertyKey should do the trick.
but if T[K] might not be cast-able to PropertyKey, you should define a function that takes an "any" and returns a PropertyKey and define the casting logic there:
if it's a string, return a new PropertyKey with the appropriate data, etc.....

edit: cast to any value that can be used as a key

Upvotes: 1

Related Questions