TS - Reduce an array of objects to an object

Viewed 2510

I want to convert an array of objects to an object

var arrays = [
    {key:'k1',value:'v1'},
    {key:'k2',value:'v2'},
    {key:'k3',value:'v3'}
];

to

{k1: "v1", k2: "v2", k3: "v3"}

This works

const object: {[k: string]: any} = {};
arrays.forEach((item) => { object[item.key] = item.value });

But I'd like how to do it using reduce.

const customData = arrays.reduce((obj, item) => (obj: Record<string, any>) => (obj[item.key] = item.value, obj), {});

returns

(obj) => (obj[item.key] = item.value) 

Thanks.

2 Answers

The callback inside reduce is not supposed to return a function but the intermediate value after the current item has been processed – in your case the object after you've assigned the current item to it.

const customData = array.reduce((obj, item) => {
  obj[item.key] = item.value;
  return obj;
}, {} as Record<string, string>)

Playground link

The problem with your code is TypeScript compiler could not infer the return type, not the object type. So, you don't need Record<string, any> for individual object which typescript can infer by itself. You would need to pass in the type of the result you would expect.

You could do it simply like this,

var arrays = [
  { key:'k1',value:'v1' },
  { key:'k2',value:'v2' },
  { key:'k3',value:'v3' }
];

const result = arrays.reduce((prev: {[key: string]: string}, curr) => {
   prev[curr.key] = curr.value;
   return prev;
}, {});

console.log(result);

Note: the result type is added in order for typescript to figure out the result type.

And, you can write that with shorthand syntax,

const result = arrays.reduce((prev: {[key: string]: string}, curr) =>  
  ({ ...prev, [curr.key]: curr.value}), {})
Related