To start off, we can utilize a const
assertion to ensure that the compiler recognizes that each property of body
is a tuple where the first element contains a filter
property and the second element contains a group
property. This is crucial for the safety of your code when accessing value[0].filter
and value[1].group
:
const body = {
A: [{ filter: [{ a: "a" }] }, { group: [{ a: "a" }] }],
B: [{ filter: [{ a: "a" }] }, { group: [{ a: "a" }] }]
} as const;
The issue at hand is that the compiler interprets your call to
array.reduce(callback, initialAccumulator)
with an
initialAccumulator
object containing empty arrays, leading it to believe that these arrays will always have no actual elements (e.g.,
Array<never>
). Therefore, when you attempt to add elements to such an array, it raises an error due to the mismatch in types. To address this, you need to provide a method to indicate or confirm that the accumulator will be storing an array of elements. Here's how you can achieve this:
interface Filter { a: string };
interface Group { a: string };
interface FiltersAndGroups {
filter: Filter[];
group: Group[];
}
// explicitly specify FiltersAndGroups as the accumulator type:
var a = Object.entries(body).reduce<FiltersAndGroups>(
(acc, [key, value]) => {
acc.filter.push(...value[0].filter);
acc.group.push(...value[1].group);
return acc;
},
{ filter: [], group: [] }
)
In this case, the types Filter
, Group
, and FiltersAndGroups
are chosen to represent the accumulator type, and the generic parameter of the reduce()
method is manually specified to prevent the erroneous inference of []
as an array of never[]
. By following this approach, the code should function without any errors. Best of luck with your implementation!
Link to code