es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo usar TypeScript con Array.prototype.reduce correctamente?

Tengo la siguiente función reduce y lo que intento no está eliminando los errores:

interface ITask {
  id: string;
  was: string;
}
// Datos de muestra:
const tasks = [
   {id: "a", was: "Foo"}, 
   {id: "b", was: "Foo"}, 
   {id: "c", was: "Bad"}
]; 
const uniqueList = tasks.reduce((acc, current) => {
  const x = acc.find((item: ITask) => item.was === current.was);
  return !x ? acc.concat(current) : acc;
}, []);

Esto me devuelve:

La propiedad 'find' no existe en el tipo 'never'.
La propiedad 'was' no existe en el tipo 'never'.
La propiedad 'concat' no existe en el tipo 'never'.

Para mí es absolutamente lógico que el valor current sea de tipo ITask y el acumulador sea de tipo ITask[]|[]. Por lo tanto, intenté lo siguiente:

const uniqueList = tasks.reduce((acc: ITask[] | [], current: ITask) => {
  const x = acc.find((item: ITask) => item.was === current.was);
  return !x ? acc.concat(current) : acc;
}, []);

Esto devuelve:

El argumento de tipo '(acc: ITask[] | [], current: ITask) => ITask[]' no se puede asignar al parámetro de tipo '(previousValue: never, currentValue: never, currentIndex: number, array: never[]) => never'.
  El tipo 'ITask[]' no se puede asignar al tipo 'never'.
El argumento de tipo 'ITask' no se puede asignar al parámetro de tipo 'ConcatArray<never>'.
  El tipo 'ITask' falta en el tipo 'ConcatArray<never>', que incluye las siguientes propiedades: length, join, slice

Editar:


A partir de los comentarios, intenté lo siguiente:

const uniqueList = tasks.reduce((acc, current: ITask) => {
  const x = acc.find((item: ITask) => item.was === current.was);
  return !x ? acc.concat(current) : acc;
}, [] as ITask[] | []);

Esto me devuelve:

La propiedad 'find' no existe en el tipo 'never'.
La propiedad 'concat' no existe en el tipo 'never'.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    El problema parece estar con el tipo inicial del acumulador de la función reduce, [ ]. TypeScript no puede inferir el tipo del acumulador a partir de un arreglo vacío [ ], por lo que lo considera como never[]. Para solucionarlo, necesitamos especificar explícitamente el tipo del parámetro acc como ITask[] o utilizar una aserción de tipo para asegurar que el arreglo [] sea de tipo ITask[]. Por lo tanto, podemos intentar una de las siguientes soluciones:

    Solución 1: Especificar explícitamente el tipo del parámetro acc.

    const uniqueList = tasks.reduce((acc: ITask[], current: ITask) => {
      const x = acc.find((item: ITask) => item.was === current.was);
      return !x ? acc.concat(current) : acc;
    }, []);
    

    Solución 2: Utilizar una aserción de tipo para asegurar que el arreglo [] sea de tipo ITask[].

    const uniqueList = tasks.reduce((acc, current: ITask) => {
      const x = acc.find((item: ITask) => item.was === current.was);
      return !x ? acc.concat(current) : acc;
    }, [] as ITask[]);
    

    En ambas soluciones, estamos especificando explícitamente el tipo del parámetro acumulador como ITask[], lo cual hace que TypeScript sea consciente del tipo y elimine los errores.

Comments are closed.