Usando sintaxe de propagação e new Set () com texto digitado

95

Estou usando o seguinte código para obter números exclusivos:

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

No entanto, o texto digitado relata o seguinte erro: O tipo 'Set' não é um tipo de matriz. Não sou um ninja datilografado, alguém poderia me dizer o que há de errado aqui?

Eggy
fonte
4
Acho que é apenas um bug do Typescript, se a versão que você está usando afirma suportar ES2015.
Pointy
1
@Pointy Desculpe por isso, devo incluir a versão do tsc que é 1.6.2
Eggy

Respostas:

46

Este é um recurso ausente. No momento, o TypeScript só oferece suporte a iteráveis ​​em Arrays.

Basarat
fonte
Obrigado pela clarificação. Vou usar .filter () ou outra coisa para fazer o trabalho. Também encontrei alguns problemas no github sobre esse erro específico. Vou ficar de olho nisso em lançamentos futuros.
Eggy
104

Atualização : Com o Typescript 2.3, agora você pode adicionar "downlevelIteration": trueao seu tsconfig, e isso funcionará ao direcionar o ES5.

A desvantagem downlevelIterationdisso é que o TS terá que injetar um pouco de boilerplate ao transpilar. A única linha da pergunta transpila com 21 linhas de texto padrão adicionado: (a partir do Typescript 2.6.1)

Este clichê será injetado uma vez por arquivo que usa iteração de nível inferior, e esse clichê pode ser reduzido usando a "importHelpers"opção por meio do tsconfig. (Veja esta postagem do blog sobre iteração de nível inferior e importHelpers)

Alternativamente, se o suporte ES5 não importa para você, você pode sempre direcionar apenas "es6" em primeiro lugar, caso em que o código original funciona sem precisar do sinalizador "downlevelIteration".


Resposta original:

Esta parece ser uma peculiaridade de transpilação ES6 datilografada. O ...operador deve trabalhar em qualquer coisa que tenha uma propriedade iteradora, (Acessado por obj[Symbol.iterator]) e Conjuntos a tenham.

Para contornar esse problema, você pode usar Array.frompara converter o conjunto para uma matriz em primeiro lugar: ...Array.from(new Set([1, 2, 3, 1, 1])).

Retsam
fonte
@Restam: O typescript fornece polyfills para Array.from no IE se "target": "es5" em tsconfig.json?
jackOfAll
1
@jackOfAll Não, Typescript não faz nenhum polyfilling de protótipos para você. Se você definir "target": "es5", será exibido um erro do compilador se você tentar usar um método que precise ser polyfilled.
Retsam
1
@Restam ótima solução com Array.from. A maioria das outras pessoas parece simplesmente desistir disso. obrigado por uma solução real!
rayepps de
Não é um bug, eles simplesmente não o suportam para o es5 destino (consulte github.com/Microsoft/TypeScript/issues/4031 ). Array.fromdeve funcionar se você tiver es2015ou superior ( es2017, esnext) em sua liblista no tsconfig.
Simon Hänisch
1
@ SimonHänisch Obrigado pelo link: atualizei minha resposta, não chamo mais de "bug", mas de "peculiaridade da transpilação", que é provavelmente um termo mais preciso. Também adicionei informações sobre a opção de iteração de nível inferior desse link, o que também resolve o problema original.
Retsam
74

Você também pode usar o método Array.from para converter o conjunto em Array

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

Nate Getch
fonte
Qual é o ponto de espalhar o array apenas para recapturá-lo em um novo array?
Robby Cornelissen
1
Se não for possível direcionar "es6", em tsconfig. E usar Definir com operador de propagação é necessário, como você faria isso?
Nate Getch
A questão é que, se você usar Array.from(), não precisará mais do operador de propagação. Isso apenas adiciona sobrecarga. let uniques = Array.from(new Set([1, 2, 3, 1, 1]));
Robby Cornelissen de
9

Você precisa definir "target": "es6",em seu tsconfig.

phil294
fonte
1

Em Javascript:

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

No texto datilografado:

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

Em estado de reação (setState):

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

Para fazê-lo funcionar, você precisa de "target": "ES6" (ou superior) ou "downlevelIteration": true em compilerOptions de seu tsconfig.json. Isso resolveu meu problema e está funcionando bem ou para mim. Espero que ajude você também.

Mayur Saner
fonte