Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lodash Reduce with Typescript - No overload matches this call

New to Typscript..

Trying to do a simple reduce using Lodash,

let collectionScenes: IScene[] = reduce(
  scenes,
  (prev, scene) =>
    scene.collectionId === action.collectionId
      ? prev.push(scene)
      : prev,
  [],
)

Having this meltdown:

(19,41): No overload matches this call.
  Overload 1 of 6, '(collection: IScene[], callback: MemoListIterator<IScene, any[], IScene[]>, accumulator: any[]): any[]', gave the following error.
    Argument of type 'IKeyArray<IScene>' is not assignable to parameter of type 'IScene[]'.
      Type 'IKeyArray<IScene>' is missing the following properties from type 'IScene[]': length, pop, push, concat, and 26 more.
  Overload 2 of 6, '(collection: List<IScene>, callback: MemoListIterator<IScene, any[], List<IScene>>, accumulator: any[]): any[]', gave the following error.
    Argument of type 'IKeyArray<IScene>' is not assignable to parameter of type 'List<IScene>'.
      Property 'length' is missing in type 'IKeyArray<IScene>' but required in type 'List<IScene>'.
  Overload 3 of 6, '(collection: IKeyArray<IScene>, callback: MemoObjectIterator<IScene, any[], IKeyArray<IScene>>, accumulator: any[]): any[]', gave the following error.
    Type 'number | any[]' is not assignable to type 'any[]'.
      Type 'number' is not assignable to type 'any[]'.

Can anyone let me know what this error is about and how to fix it?

like image 729
beek Avatar asked Jan 17 '26 11:01

beek


1 Answers

You have a problem with your reducer:

(prev, scene) =>
  scene.collectionId === action.collectionId
   ? prev.push(scene)
     ^^^^^^^^^^^^^^^^
   : prev

Array#push returns a number. It's the new length of the array:

const arr = ["a", "b", "c"];

console.log(arr.length);
console.log(arr.push("d"));
console.log(arr.push("e"));

So, on the next iteration of reduce, the value of the accumulator prev would be equal to that number not to an array.

You need to add a value and still return an array:

prev.push(scene);
return prev;

But since this is cumbersome in a conditional operator, you can make the addition a single expression if you use:

Array#concat

(prev, scene) =>
  scene.collectionId === action.collectionId
   ? prev.concat(scene)
     ^^^^^^^^^^^^^^^^^^
   : prev

Spread syntax

(prev, scene) =>
  scene.collectionId === action.collectionId
   ? [...prev, scene]
     ^^^^^^^^^^^^^^^^
   : prev
like image 163
VLAZ Avatar answered Jan 20 '26 02:01

VLAZ



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!