Typescript: for..of com iteradores

Criado em 14 mai. 2015  ·  9Comentários  ·  Fonte: microsoft/TypeScript

Seria bom se a nova sintaxe for (let value of values) funcionasse com iteradores; ie:

for (let value of myMap.values()) {
    doSomething(value);
}

Relacionado com # 2695.

Question

Comentários muito úteis

Acho isso muito decepcionante. Posso usar for-of com qualquer ES5 iterável e de destino com Traceur e Babel hoje. Estou interessado em propor que nossa equipe mude de Traceur para TypeScript, mas esta limitação no TypeScript impedirá que isso aconteça. Quando o TypeScript diz que pretende ser um superconjunto do ES6, acho que precisa incluir a capacidade de direcionar os navegadores ES5 para todos os recursos ES6 que ele suporta.

Todos 9 comentários

Isso já é permitido se seu destino for ES6:

interface MyMap<T> {
    values(): Iterable<T>;
}
var myMap: MyMap<string>;

for (let value of myMap.values()) {
    var s: string = value;
}

A razão pela qual isso não é permitido em ES5 / ES3 são:

  • Um dos axiomas do TypeScript é não fazer emissão direcionada ao tipo. ou seja, que o código emitido não depende do que o sistema de tipos pensa sobre seu código, mas sim como uma transformação sintática de sua fonte de entrada.
  • Fazer a emulação completa do iterador significa que temos que depender de um pollyfill para o Symbol, outra qualidade que gostamos de manter
  • A lógica de iteração completa gerada não é cheep, você precisa chamar next () e verificar done, se falhar, retornar se não usar o valor. trata-se de despacho adicional, duas pesquisas de propriedade e uma alocação de objeto em cada iteração de um loop. Tentamos manter o código emitido simples e relacionável com a fonte, especialmente nas características de desempenho
  • Finalmente, para fazer tudo isso em objetos iteráveis ​​personalizados, ainda precisamos fazê-lo em Arrays, uma vez que Arrays não tem esse suporte em ES5 / ES3 e não queremos fazer emissão dirigida por tipo, precisamos converter um array para um iterável, que é drasticamente mais lento do que o loop for normal. e o principal problema é que, ao observar um loop em uma matriz, não fica claro que isso incorreria em custos.

Como resultado desses fatores, no ES3 / ES5 apenas os arrays são permitidos em loops for..of (como os objetos iteráveis ​​mais comuns disponíveis na linguagem JS atualmente); quanto à segmentação ES6 (ou seja, com suporte a mecanismo de tempo de execução para iteráveis ​​e arrays iteráveis), iteráveis ​​personalizados são permitidos além de Array, string, map e set, .. etc.

Entendido...
@mhegazy Muito obrigado pela sua resposta detalhada !!!

Acho isso muito decepcionante. Posso usar for-of com qualquer ES5 iterável e de destino com Traceur e Babel hoje. Estou interessado em propor que nossa equipe mude de Traceur para TypeScript, mas esta limitação no TypeScript impedirá que isso aconteça. Quando o TypeScript diz que pretende ser um superconjunto do ES6, acho que precisa incluir a capacidade de direcionar os navegadores ES5 para todos os recursos ES6 que ele suporta.

Acho que poderia usar o TypeScript para direcionar o ES6 e, em seguida, executar essa saída por meio do Traceur ou Babel. Eu realmente não quero ter que fazer isso.

Como uma atualização para este problema, o protocolo do iterador agora é compatível com o destino ES3 / ES5 usando --downlevelIteration . Veja # 12346 para mais informações.

Parece que isso deve ser corrigido para TS 2.3, mas estou executando o TS 2.3.3 e

      for (let [ i, observationPoint ] of observationPointsList.entries())
        observationPoints[ observationPoint.spot || (i + 1) ] = observationPoint;

onde observationPointsList é um ObservationPointModel[] , produz:

[11:30:56]  typescript: src/models/observation-set.ts, line: 44 
            Type 'IterableIterator<[number, ObservationPointModel]>' is not an array type or a string type. 

Estou esquecendo de algo?

Ah, é verdade. Não consigo ver nesta documentação ou no # 12346 - por que isso está oculto por trás de uma opção em oposição ao comportamento padrão? Isso sempre será opcional?

@lhunath está nas informações de lançamento oficial para 2.3 . É opcional porque tem um impacto muito significativo no tamanho do código gerado e, potencialmente, no desempenho, para todos os usos de iteráveis ​​(incluindo arrays). Acho que a compensação compensa o aumento da expressividade, mas tornar o código existente mais lento e complexo parece uma justificativa razoável para a existência de um sinalizador.

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

Zlatkovsky picture Zlatkovsky  ·  3Comentários

dlaberge picture dlaberge  ·  3Comentários

Roam-Cooper picture Roam-Cooper  ·  3Comentários

blendsdk picture blendsdk  ·  3Comentários

wmaurer picture wmaurer  ·  3Comentários