Utilizzo della sintassi diffusa e del nuovo Set () con dattiloscritto


95

Sto usando il seguente codice per ottenere numeri univoci:

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

Tuttavia, il dattiloscritto riporta l'errore seguente: Il tipo "Set" non è un tipo di matrice. Non sono un ninja dattiloscritto, qualcuno potrebbe dirmi cosa c'è che non va qui?


4
Penso che sia solo un bug di Typescript, se la versione che stai utilizzando afferma di supportare ES2015.
Pointy

1
@Pointy Mi dispiace, dovrei includere la versione di tsc che è 1.6.2
Eggy

Risposte:


46

Questa è una caratteristica mancante. TypeScript al momento supporta solo gli iterabili sugli array.


Grazie per il chiarimento. Userò .filter () o qualcos'altro per portare a termine il lavoro. Ho anche riscontrato alcuni problemi su GitHub riguardo a questo particolare errore. Terrò d'occhio questo nelle versioni future.
Eggy

104

Aggiornamento : con Typescript 2.3, ora puoi aggiungere "downlevelIteration": trueal tuo tsconfig, e questo funzionerà mentre prendi di mira ES5.

Lo svantaggio di downlevelIterationè che TS dovrà iniettare un bel po 'di boilerplate durante il transpiling. La singola riga della domanda si trasporta con 21 righe di boilerplate aggiunto: (come da Typescript 2.6.1)

Questo boilerplate verrà iniettato una volta per file che utilizza l'iterazione di livello inferiore e questo boilerplate può essere ridotto utilizzando l' "importHelpers"opzione tramite tsconfig. (Vedi questo post del blog sull'iterazione di livello inferiore e importHelpers)

In alternativa, se il supporto ES5 non è importante per te, puoi sempre scegliere come target "es6" in primo luogo, nel qual caso il codice originale funziona senza bisogno del flag "downlevelIteration".


Risposta originale:

Questa sembra essere una stranezza di traspolazione ES6 dattiloscritta. L' ...operatore dovrebbe lavorare su tutto ciò che ha una proprietà iteratore, (Accessed by obj[Symbol.iterator]) e Sets ha quella proprietà.

Per ovviare a questo, è possibile utilizzare Array.fromper convertire il set a un array prima: ...Array.from(new Set([1, 2, 3, 1, 1])).


@Restam: il dattiloscritto fornisce polyfill per Array.from in IE se "target": "es5" in tsconfig.json?
jackOfAll

1
@jackOfAll No, Typescript non esegue il polyfilling dei prototipi per te. Se imposti "target": "es5" dovrebbe darti un errore del compilatore se tenti di usare un metodo che deve essere polyfilled.
Retsam

1
@Restam ottima soluzione con Array.from. La maggior parte delle altre persone sembra rinunciare a questo. grazie per una vera soluzione!
rayepps

Non è un bug, semplicemente non lo supportano per il es5target (vedi github.com/Microsoft/TypeScript/issues/4031 ). Array.fromdovrebbe funzionare se hai es2015o superiore ( es2017, esnext) libnell'elenco in tsconfig.
Simon Hänisch,

1
@ SimonHänisch Grazie per il link: ho aggiornato la mia risposta, non lo chiamo più un "bug", ma una "stranezza di transpilation", che è probabilmente un termine più preciso. Ho anche aggiunto informazioni sull'opzione di iterazione di livello inferiore da quel collegamento, che risolve anche il problema originale.
Retsam

74

È inoltre possibile utilizzare il metodo Array.from per convertire il set in array

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


Qual è lo scopo di diffondere la matrice solo per riconquistarla in una nuova matrice?
Robby Cornelissen

1
Se non è possibile scegliere come target "es6", in tsconfig. E l'utilizzo di Set with spread operator è obbligatorio, come lo faresti?
Nate Getch

Il punto è che se usi Array.from(), non hai più bisogno dell'operatore spread. Aggiunge solo un sovraccarico. let uniques = Array.from(new Set([1, 2, 3, 1, 1]));
Robby Cornelissen

9

Devi impostare "target": "es6",nel tuo tsconfig.


1

In Javascript:

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

In dattiloscritto:

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

In React State (setState):

setCart(Array.from(new Set([...cart, {title: 'Sample', price: 20}])));

0

Per farlo funzionare, hai bisogno di "target": "ES6" (o superiore) o "downlevelIteration": true nelle compilerOptions del tuo tsconfig.json. Questo ha risolto il mio problema e ha funzionato bene o me. Spero che possa aiutare anche te.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.