If you don't know how many things you're spreading, you can't write the code to spread them with .... It's just like + in that way: You can add three things together (a + b + c), but if you don't know how many you're adding, you can't directly write the code for it.
Your reduce could use spread rather than concat (but keep reading):
const arrays = [[1,2,3],[4,5,6]];
console.log(arrays.reduce((a,b)=>[...a, ...b]));
But both that and concat are inefficient (which may or may not matter) because they create a new array and re-copy the elements that have already been copied for every input. If efficiency is a constraint, just use a simple loop:
const arrays = [[1,2,3],[4,5,6]];
const result = [];
for (const entry of arrays) {
result.push(...entry);
}
console.log(result);
Or if you really like doing it in a single expression, you can shoehorn it into a reduce (because basically any array operation can be shoehorned into a reduce):
const arrays = [[1,2,3],[4,5,6]];
console.log(arrays.reduce((acc,entry) => {
acc.push(...entry);
return acc;
}, []));
I'm with Brian Terlson, though: For me, reduce is overused.
In closing, for this specific issue, we're getting flat now:
const arrays = [[1,2,3],[4,5,6]];
console.log(arrays.flat());
arrays.flat()or[].concat(...arrays)....isn't an operator. It doesn't really matter much, but that's why you can't just use it in any expression context.