Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

224
Views
JS a TS: el tipo 'null' no se puede asignar al tipo 'number'

Soy nuevo en TypeScript y acabo de comenzar a migrar mi aplicación de JavaScript a TypeScript.

  1. Primera función: calcAvg , toma una matriz de números y devuelve su promedio.
  2. Segunda función: avgRoasDiscrepancy , toma dos matrices, si las dos matrices tienen la misma longitud y no tienen valores nulos, restará cada elemento de una lista con el elemento en el mismo índice de la segunda matriz.

El problema está en la siguiente función de map (ver el código completo a continuación):

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

Obtuve el siguiente 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'

No sé cómo "convencer" a TypeScript de que tanto value como roasArray[index] son, de hecho, números y no valores nulos.

Aquí está el código completo:

 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'; };
over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

en esta línea

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

Está suponiendo que los elementos de clientRoasArray podrían ser number o podrían ser null y esto está claro en su condición : null

Y en esta línea, está identificando el valor de clientRoasArray solo como un number only , lo cual es incorrecto porque le dijo a su código que el valor podría ser number|null

Todo lo que necesitas es cambiar esta línea

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

a esto

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

pero enfrentará un problema con roasArray[index] porque también podría ser null

over 4 years ago · Santiago Trujillo Report

0

No pude hacer que la inferencia de tipo funcionara correctamente usando every las llamadas en las matrices, sin embargo, puede hacer una protección de tipo para ayudar al compilador a comprender que las matrices son del tipo number[] en lugar de (number | null)[] . Esto también ayudará con la refactorización un poco.

Tenga en cuenta que también hay un problema con su lógica de verificación de tipo actual, pero parece que es solo un error tipográfico: el !! antes de que la primera condición debería ser solo una ! .

Aquí hay un protector de tipo simple:

 function isNonNullNumberArray(x: (number | null)[]): x is number[] { return x.every(e => e !== null); }

Entonces puedes usar isNonNullNumberArray así:

 if (!(isNonNullNumberArray(clientRoasArray) && isNonNullNumberArray(roasArray))) { //if one of the arrays has null values don't calculate return 'no data'; } // now the compiler knows that neither array contains null values if (clientRoasArray.length === roasArray.length) { const discArray = clientRoasArray.map((value: number, index: number) => value - roasArray[index]); return calcAvg(discArray); } return 'no data';

También podría hacer una protección de tipo más general como esta si quisiera usar genéricos para que funcione para tipos distintos de number :

 function isNonNullArray<T>(x: T[]): x is Exclude<T, null>[] { return x.every(e => e !== null); }

Por cierto, no es necesario que declare explícitamente los tipos de parámetros en las funciones que se pasan al map y otros métodos de matriz, ya que el compilador puede inferir los tipos en función de la firma del método de matriz (por ejemplo, map ).

over 4 years ago · Santiago Trujillo Report

0

¡Puede verificar si su variable no es null y usar ! (operador de aserción no nulo) para decirle a TypeScript que la expresión no puede ser null . También el tipo de value es number | null

 if (clientRoasArray.length === roasArray.length) { const discArray = clientRoasArray.map((value: number | null, index: number) => { return value && roasArray[index] ? value - roasArray[index]! : null }); return calcAvg(discArray as number[]); }
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!