Search code examples
javascripttypescripttypescript-genericsreduce

How to use typescript in reduce function


My code:

const calculateSum = <T>(array: T[], key: string): number => {
  const total = array.reduce<number>((accumulator, object: T) => {
    return accumulator + object[key];
  }, 0);

  return total;
};

type TProjectServiceList = {
  id: number;
  sum: number;
};

const services = [
  {id: 1, sum: 78.09},
  {id: 2, sum: 105.09},
  {id: 3, sum: 8.45}
]

const totalSum = calculateSum<TProjectServiceList>(services, 'sum');

I got Typescript error:

object[key] - Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'unknown'. No index signature with a parameter of type 'string' was found on type 'unknown'.ts(7053)

How to make this function with typescript generics?


Solution

  • Nowhere in the definition of calculateSum is the type of T mentioned. So the compiler is obviously unaware of the type of the values of keys of T. Hence, the error.

    You can specify that T extends a particular type and make life easy for the compiler.

    Given that you are trying to add these values I would like to assume that the values are all of type number. Here is a solution for now:

    const calculateSum = <T extends { [id : string] : number}>(array: T[], key: string): number => {
      const total = array.reduce<number>((accumulator, obj: T) => {
        return accumulator + obj[key];
      }, 0);
    
      return total;
    };
    
    type TProjectServiceList = {
      id: number;
      sum: number;
    };
    
    const services = [
      {id: 1, sum: 78.09},
      {id: 2, sum: 105.09},
      {id: 3, sum: 8.45}
    ]
    
    const totalSum = calculateSum<TProjectServiceList>(services, 'sum');
    

    Link