Home > Net >  Typescript always types the result of reduce function as any if the array is any[]
Typescript always types the result of reduce function as any if the array is any[]

Time:12-31

I have a reduce function that takes an array of anys and should produce an array of some type. However typescript is always assigning any[] to the result of the reduce function. No matter if I type the initial value with the proper type or if I type the callback return type with the proper value, I always get an array of any. Is this correct or a bug on TS?

Here you have a basic example:

type Employee = { x: boolean }
type Item = {}
type Results =  {data: any[]} 

const doStuff = (results: Results, employees: Employee[]) => {
  const nonExistingEmployees: string[] = [];
  const pensionsInputs = results.data?.reduce((acc: Item[], item: Item) => {
    return acc;
  }, []);
  return { pensionsInputs, nonExistingEmployees };
};

Playground link

CodePudding user response:

Type the accumulator, not the initial value:

const x = results.data.reduce((acc: Item[], item) => { return acc.concat({x: item.x}) }, [])

This will provide type checking for anything you do with acc inside the callback function, although item will still be any unless you also provide a new type for that.

Edit:

This is not something I was aware of but it turns out that providing a new type for both accumulator and current values will revert the function override which happens when providing a type for just the accumulator.

So another way to type this in your new code sample might be:

const pensionsInputs = (results.data as Item[]).reduce((acc: Item[], item) => {
  return acc;
}, []);

item is now automatially typed as Item. You could just as well do what the other commenter suggested and forget typing the individual elements of the reduce call, instead just asserting that it is an Item[] after the fact, the only difference being you don't get type checking inside the callback function.

Or else just assert that results is what you think it is as soon as you get it, before trying to do anything else with it - this is probably the cleanest solution without doing any of your own validation. And you probably should be doing your own validation instead of any of this if you're not 100% sure about what the result will be at run time.

  • Related