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?


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.


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])).


@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);


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.


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}])));

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.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.