Home > Back-end >  How to fix argument of type is is not assignable to parameter of type
How to fix argument of type is is not assignable to parameter of type

Time:06-08

I'm trying to filter my array of objects in react type script. Got this error.Here is my interface , state and function

TS2345: Argument of type '(prev: IBudget, current: IBudget) => IBudget | undefined' is not assignable to parameter of type '(previousValue: IBudget, currentValue: IBudget, currentIndex: number, array: IBudget[]) => IBudget'.
Type 'IBudget | undefined' is not assignable to type 'IBudget'. Type 'undefined' is not assignable to type 'IBudget'.

 export interface IBudget {
    title?:string,
    price?:number,
    date?: Date,
}

const [expenses,setExpenses] = useState<IBudget[]>([])

  if (!isEmpty(expenses)){
        const max = expenses.reduce((prev , current)=> {
            if( prev !== undefined) {
                if (prev.price !== undefined && current.price !== undefined){
                    return (prev.price > current.price) ? prev : current
                }
            }
        }) 
    }


CodePudding user response:

This is probably happening because you didn't pass an initial value to the reduce function, and given your implementation you could pass the first argument of the expenses array

const max = expenses.reduce((prev, current) => {
 if (prev !== undefined) {
   if (prev.price !== undefined && current.price !== undefined) {
     return prev.price > current.price ? prev : current;
   }
 }
}, expenses[0]);

after you do that you probably will have another error saying that the previous or the current types do not match with undefined. And this would be because you have if's that could potentially not be entered right? and if that happens your code will return undefined to the next interaction.

In order to fix that you need to make sure that some value is returned to the next iteration, as below:

const max = expenses.reduce((prev, current) => {
 if (prev !== undefined) {
   if (prev.price !== undefined && current.price !== undefined) {
     return prev.price > current.price ? prev : current;
   }
 }

 // here you might have to adjust to your needs
 return current;
}, expenses[0]);

CodePudding user response:

The type definition of reduce will automatically set the return type to the type of array - number[] is assumed to reduce to number.

You can override this by passing a initialValue of the same type as you expect the return to be, or by setting it using generics (or both):

[1,2,3].reduce<number | string>(...)

In your case, it's unclear what your desired result is. Do you intend to have undefined possibly be returned? If not, you need to handle the cases where your 2 if statements do not pass, since the absence of a return is what is causing the undefined type inference.

If you do want the possibility of undefined, you could simply set the type, and pass in an initialValue:

const max = expenses.reduce<IBudget | undefined>((prev , current)=> {
  if( prev !== undefined) {
    if (prev.price !== undefined && current.price !== undefined){
      return (prev.price > current.price) ? prev : current
    }
  }
}, undefined) 
  • Related