Usando la sintaxis de propagación y el nuevo Set () con mecanografiado


91

Estoy usando el siguiente código para obtener números únicos:

let uniques = [ ...new Set([1, 2, 3, 1, 1]) ]; // [1, 2, 3]

Sin embargo, error de seguimiento de informe mecanografiado: El tipo 'Set' no es un tipo de matriz. No soy un ninja mecanografiado, ¿alguien podría decirme qué pasa aquí?


4
Creo que es solo un error de TypeScript, si la versión que estás usando afirma ser compatible con ES2015.
Puntiagudo

1
@Pointy Lo siento, debería incluir la versión de tsc que es 1.6.2
Eggy

Respuestas:


39

Esta es una característica que falta. TypeScript solo admite iterables en Arrays en este momento.


Gracias por la aclaración. Usaré .filter () o algo más para hacer el trabajo. También encontré algunos problemas en github sobre este error en particular. Estaré atento a esto en futuras versiones.
Eggy

95

Actualización : con Typescript 2.3, ahora puede agregar "downlevelIteration": truea su tsconfig, y esto funcionará mientras apunta a ES5.

La desventaja downlevelIterationes que TS tendrá que inyectar un poco de repetición cuando se transpile. La única línea de la pregunta se transpila con 21 líneas de texto estándar agregado: (a partir de TypeScript 2.6.1)

Este texto estándar se inyectará una vez por archivo que utilice iteración de nivel inferior, y este texto estándar se puede reducir usando la "importHelpers"opción a través de tsconfig. (Vea esta publicación de blog sobre iteración de nivel inferior y importHelpers)

Alternativamente, si la compatibilidad con ES5 no le importa, siempre puede apuntar a "es6" en primer lugar, en cuyo caso el código original funciona sin necesidad de la marca "downlevelIteration".


Respuesta original:

Esto parece ser una peculiaridad de transpilación de ES6 mecanografiado. El ...operador debe trabajar en cualquier cosa que tenga una propiedad de iterador, (Accedido por obj[Symbol.iterator]) y los Conjuntos tengan esa propiedad.

Para evitar esto, se puede utilizar Array.frompara convertir el conjunto en una matriz primero: ...Array.from(new Set([1, 2, 3, 1, 1])).


@Restam: ¿El mecanografiado proporciona polyfills para Array.from en IE si "target": "es5" en tsconfig.json?
jackOfAll

1
@jackOfAll No, Typescript no hace ningún polyfilling de prototipos por usted. Si establece "target": "es5", debería generar un error de compilación si intenta utilizar un método que necesita ser polietileno.
Retsam

1
@Restam gran solución con Array.from. La mayoría de la gente parece simplemente darse por vencida en esto. gracias por una solución real!
rayepps

No es un error, simplemente no lo admiten para el es5objetivo (consulte github.com/Microsoft/TypeScript/issues/4031 ). Array.fromdebería funcionar si tiene es2015o superior ( es2017, esnext) en su liblista en tsconfig.
Simon Hänisch

1
@ SimonHänisch Gracias por el enlace: he actualizado mi respuesta, ya no lo llamo un "error", sino una "peculiaridad de transpilación", que probablemente sea un término más preciso. También agregué información sobre la opción de iteración de nivel inferior de ese enlace, que también resuelve el problema original.
Retsam

67

También puede usar el método Array.from para convertir el conjunto en matriz

let uniques = Array.from(new Set([1, 2, 3, 1, 1])) ;
console.log(uniques);


¿Cuál es el punto de extender la matriz solo para recapturarla en una nueva matriz?
Robby Cornelissen

1
Si no es posible apuntar a "es6", en tsconfig. Y se requiere el uso de Establecer con operador de propagación, ¿cómo lo haría?
Nate Getch

El punto es que si lo usa Array.from(), ya no necesita el operador de propagación. Simplemente agrega gastos generales. let uniques = Array.from(new Set([1, 2, 3, 1, 1]));
Robby Cornelissen


0

Para que funcione, necesita "target": "ES6" (o superior) o "downlevelIteration": true en compilerOptions de su tsconfig.json. Esto resolvió mi problema y funciona bien o para mí. Espero que también te ayude.


-1

En Javascript:

[ ...new Set([1, 2, 3, 1, 1]) ]

En mecanografiado:

Array.from(new Set([1, 2, 3, 1, 1]))

En estado de reacción (setState):

setCart(Array.from(new Set([...cart, {title: 'Sample', price: 20}])));
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.