Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JS to TS: Type 'null' is not assignable to type 'number'

I am new to TypeScript and have just started migrating my application from JavaScript to TypeScript.

  1. First function: calcAvg, takes an array of numbers and returns their average.
  2. Second function: avgRoasDiscrepancy, takes two arrays, if the two arrays are of equal length and with no null values, it will subtract each element from one list with the element in the same index from the second array.

The issue is in the following map function (see full code below):

const discArray = clientRoasArray.map((value: number, index: number) => value - roasArray[index]);

I get the following error:

Argument of type '(value: number, index: number) => number' is not assignable to parameter of type '(value: number | null, index: number, array: (number | null)[]) => number'.
Types of parameters 'value' and 'value' are incompatible.
Type 'number | null' is not assignable to type 'number'.
Type 'null' is not assignable to type 'number'

I don't know how to "convince" TypeScript that both value and roasArray[index] are in fact numbers and not nulls.

Here is the complete code :

interface DailyData {
  id: number
  clientCost:number
  conValue:number
  clientConvValue:number
  margin: number

}

const calcAvg = (dataList: number[]) => {
  const reducer = (accumulator: number, curr: number) => accumulator + curr;
  const dataSum = dataList.reduce(reducer, 0);
  return dataSum / dataList.length;
};


const avgRoasDiscrepancy = (advertiserStats: DailyData[]) => {
  const clientRoasArray = advertiserStats.map((obj: DailyData) => obj.clientCost > 0 ? obj.clientConvValue/obj.clientCost: null);
  const roasArray = advertiserStats.map((obj: DailyData) => obj.clientCost > 0 ? obj.conValue/obj.clientCost: null);
  if (clientRoasArray.length === 0 || roasArray.length === 0) {
    return 'no data'
  }
  if (!!clientRoasArray.every((el: number|null) => el!== null) || (!roasArray.every((el: number|null) => el!== null) )) {
    //if one of the arrays has null values don't calculate
    return 'no data';
  }
  if (clientRoasArray.length === roasArray.length) {
    const discArray = clientRoasArray.map((value: number, index: number) => value - roasArray[index]);
    return calcAvg(discArray as number[]);
  }
  return 'no data';

};
like image 544
Limor Avatar asked Oct 19 '25 02:10

Limor


1 Answers

In this line

  const clientRoasArray = advertiserStats.map((obj: DailyData) => obj.clientCost > 0 ? obj.clientConvValue/obj.clientCost: null);

You are assuming that the elements of clientRoasArray could be number or could be null and this is clear in your condition : null

And in this line, you are identifying the value of the clientRoasArray as number only which is wrong because you told your code that the value could be number|null

All you need is to change this line

const discArray = clientRoasArray.map((value: number, index: number) => value - roasArray[index]);

to this

const discArray = clientRoasArray.map((value: number | null, index: number) => value - roasArray[index]);

but you will face an issue with roasArray[index] because it also could be null

like image 194
Mohammed naji Avatar answered Oct 20 '25 17:10

Mohammed naji



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!