Estoy tratando de crear una función, que tome una matriz de números o una matriz de cadenas y devuelva Set de esa matriz, así:
const f = (arr: number[] | string[]): number[] | string[] => { return [...new Set(arr)]; }Y obteniendo un error:
Ninguna sobrecarga coincide con esta llamada.
Sobrecarga 1 de 2, '(¿iterable?: Iterable | nulo | indefinido): Conjunto', dio el siguiente error. Argumento de tipo 'número[] | string[]' no es asignable al parámetro de tipo 'Iterable | nulo | indefinido'. El tipo 'string[]' no se puede asignar al tipo 'Iterable'. Los tipos devueltos por 'Symbol.iterator.next(...)' son incompatibles entre estos tipos. El tipo 'IteratorResult<string, any>' no se puede asignar al tipo 'IteratorResult<number, any>'. El tipo 'IteratorYieldResult' no se puede asignar al tipo 'IteratorResult<number, any>'. El tipo 'IteratorYieldResult' no se puede asignar al tipo 'IteratorYieldResult'. El tipo 'cadena' no se puede asignar al tipo 'número'.
Sobrecarga 2 de 2, '(¿valores?: número de solo lectura[] | nulo | indefinido): Conjunto', dio el siguiente error. Argumento de tipo 'número[] | string[]' no se puede asignar al parámetro de tipo 'readonly number[] | nulo | indefinido'. El tipo 'cadena []' no se puede asignar al tipo 'número de solo lectura []'. El tipo 'cadena' no se puede asignar al tipo 'número'.
Puedo cambiar el tipo entrante de number[] | string[] a (number | string)[] pero significa que en la matriz podría haber números y cadenas al mismo tiempo, eso no es lo que quiero .
const f = (arr: (number | string)[]): (number | string)[] => { return [...new Set(arr)]; } f([1,2,3]); // ok f(['1','2','3']); // ok f([1,2,'3','4']); // ok, but should be err f([true, {}, 1]); // err, like it should beEDITAR: parece que esto se relaciona con algunas configuraciones de TS. Una forma es distribuir la matriz a partir de la cual está creando el conjunto y emitir el valor de retorno, así:
const f = (arr: number[] | string[]): number[] | string[] => { return Array.from(new Set([...arr])) as number[] | string[]; } Como dice udalmik, puedes usar any cosa que anule el punto.
Puedes deshacerte de este error lanzando un argumento a any[] :
function f(arg: number[] | string[]): number[] | string[] { return [...new Set(arg as any[])]; }Creo que cualquiera de estos podría funcionar mejor.
const f = <T extends number[] | string[]>(arr: T): T => { return <T> [...new Set(arr as any[])]; } let f1 = f([1,2,3,4,5,5,5]); let f2 = f(['a','b','c','c','c']); let f3 = f(['a','b','c','a','b',1,2,3,4]);//error function f(arr:number[]):number[]; function f(arr:string[]):string[]; function f(arr:any[]):any[]{ return [...new Set(arr)]; } let f1 = f([1,2,3,4,5,5,5]); let f2 = f(['a','b','c','c','c']); let f3 = f(['a','b','c','a','b',1,2,3,4]);//errorDe esta forma, la función solo acepta matrices de números o cadenas, pero no ambas, y conserva la información del tipo de retorno. Si pasa una matriz de números, TypeScript sabe que el valor devuelto es una matriz de números.