Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

227
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar

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 Denunciar

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda