Filippo Rivolta
Filippo Rivolta

Reputation: 324

array reduce not correctly inferring types

i am having some troubles with array reduce in Typescript. To simplify, let's say I have a simple array of numbers where I want to remove duplicates and return a new array without them I was used to do something like this using reduce:

const new = nums.reduce((acc, item) => acc.includes(item) ? acc : [...acc, item], [])

where: nums = [0, 0, 1, 1, 1, 2, 2, 3, 3, 4] and new should be: new = [0, 1, 2, 3, 4]

I have tried to type the function like this:

const new: number[] = nums.reduce((acc: number[], item:number) => acc.includes(item) ? acc : [...acc, item], [])

I receive the following error for "new":

TS2322: Type 'number' is not assignable to type 'number[]'.

and an error on the accumulator:

TS2769: No overload matches this call.

Seems like there is no way of telling typescript that the accumulator should be an array of numbers, any solution?

Upvotes: 0

Views: 1174

Answers (2)

KiraLT
KiraLT

Reputation: 2607

According to reduce function types:

reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U;

The return value is inferred from the initialValue. So you can either cast initialValue:

nums.reduce((acc, item) => acc.includes(item) ? acc : [...acc, item], [] as number[])

Or rewrite template argument:

nums.reduce<number[]>((acc, item) => acc.includes(item) ? acc : [...acc, item], [])

Upvotes: 3

Orinayo Oyelade
Orinayo Oyelade

Reputation: 347

Do this nums.reduce<number[]>(...) to tell TypeScript what reduce will return

Upvotes: 2

Related Questions