¿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'.
davy.ai
El problema parece estar con el tipo inicial del acumulador de la función
reduce
,[ ]
. TypeScript no puede inferir el tipo delacumulador
a partir de un arreglo vacío[ ]
, por lo que lo considera comonever[]
. Para solucionarlo, necesitamos especificar explícitamente el tipo del parámetroacc
comoITask[]
o utilizar una aserción de tipo para asegurar que el arreglo[]
sea de tipoITask[]
. Por lo tanto, podemos intentar una de las siguientes soluciones:Solución 1: Especificar explícitamente el tipo del parámetro
acc
.Solución 2: Utilizar una aserción de tipo para asegurar que el arreglo
[]
sea de tipoITask[]
.En ambas soluciones, estamos especificando explícitamente el tipo del parámetro
acumulador
comoITask[]
, lo cual hace que TypeScript sea consciente del tipo y elimine los errores.