Home > Enterprise >  Allow only keys from type of the object in an array
Allow only keys from type of the object in an array

Time:06-27

export const groupBy = <T, K extends keyof T>(key: K, array: T[]) =>
  array.reduce((objectsByKeyValue, obj) => {
    const value = obj[key];
    objectsByKeyValue[value] = (objectsByKeyValue[value] || 0)   1;
    return objectsByKeyValue;
  }, {});

I want to allow the keys only from the type of object in the array. I implemented this function but line number 4 throws an error saying Type 'T[K]' cannot be used to index type '{}'. expectation is once the user passes the object array I want to group the objects by property of that object and the count of that property. This is the working JS Example

CodePudding user response:

So there is no correct way to type this. You want to have the keys of your new object to be a union of all the possible values of the keys in your array objects. These values are not available at compile time so it is not possible to type them.

That being said, your current error is because of your second param for reduce(). It is {} and since you haven't typed reduce properly, TS infers the type of objectsByKeyValue to be {} and does not allow any properties to be added.

Adding an any will do:

export const groupBy = <T, K extends keyof T>(key: K, array: T[]) =>
  array.reduce<any>((objectsByKeyValue, obj) => {
    const value = obj[key];
    objectsByKeyValue[value] = (objectsByKeyValue[value] || 0)   1;
    return objectsByKeyValue;
  }, {});

Another way could be to define a simple interface with keys as string and value as number:

type ReturnType = {
  [k in string]?: number;

};


  export const groupByNew = <T, K extends keyof T>(key: K, array: T[]) =>
  array.reduce<ReturnType>((objectsByKeyValue, obj) => {
    const value = obj[key] as unknown as string;
    objectsByKeyValue[value] = (objectsByKeyValue[value] || 0)   1;
    return objectsByKeyValue;
  }, {});

Playground

  • Related