Typescript: for..of avec itérateurs

Créé le 14 mai 2015  ·  9Commentaires  ·  Source: microsoft/TypeScript

Ce serait bien si le nouveau sintax for (let value of values) fonctionne avec des itérateurs; c'est à dire:

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

Associé à # 2695.

Question

Commentaire le plus utile

Je trouve cela vraiment décevant. Je peux utiliser for-of avec n'importe quel ES5 itérable et cible avec Traceur et Babel aujourd'hui. Je suis intéressé à proposer que notre équipe passe de Traceur à TypeScript, mais cette limitation de TypeScript empêchera que cela se produise. Lorsque TypeScript dit qu'il vise à être un sur-ensemble d'ES6, je pense que cela doit inclure la possibilité de cibler les navigateurs ES5 pour toutes les fonctionnalités ES6 qu'il prend en charge.

Tous les 9 commentaires

Ceci est déjà autorisé si votre cible est ES6:

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

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

Les raisons pour lesquelles cela n'est pas autorisé dans ES5 / ES3 sont:

  • L'un des axiomes de TypeScript est de ne pas faire d'émissions dirigées par type. c'est-à-dire que le code émis ne dépend pas de ce que le système de types pense de votre code, mais plutôt comme une transformation syntaxique de votre source d'entrée.
  • Faire l'émulation complète de l'itérateur signifiera que nous devrons dépendre d'un pollyfill pour Symbol, encore une fois une autre qualité que nous aimons conserver
  • La logique d'itération complète générée n'est pas cheep, vous devez appeler next () et vérifier terminé, si elle échoue, retournez sinon utilisez la valeur. il s'agit d'une répartition supplémentaire, de deux recherches de propriétés et d'une allocation d'objet à chaque itération d'une boucle. Nous avons essayé de garder le code émis simple et comparable à la source, en particulier dans les caractéristiques de performance
  • Enfin, pour faire tout cela sur des objets itérables personnalisés, nous devons toujours le faire sur des tableaux, car les tableaux n'ont pas ce support dans ES5 / ES3, et nous ne voulons pas faire une émission dirigée par type, nous devons convertir un tableau à un itérable, qui est considérablement plus lent que votre boucle for normale. et le principal problème est qu'il n'est pas clair, en regardant une boucle sur un tableau, que cela entraînerait ce coût.

En raison de ces facteurs, dans ES3 / ES5, seuls les tableaux sont autorisés dans les boucles for..of (en tant qu'objets itérables les plus courants disponibles dans le langage JS aujourd'hui); comme pour le ciblage d'ES6 (c'est-à-dire avec le support du moteur d'exécution pour les itérables et les tableaux itérables) les itérables personnalisés sont autorisés en plus de Array, string, map et set, .. etc.

Compris...
@mhegazy Merci beaucoup pour votre réponse détaillée !!!

Je trouve cela vraiment décevant. Je peux utiliser for-of avec n'importe quel ES5 itérable et cible avec Traceur et Babel aujourd'hui. Je suis intéressé à proposer que notre équipe passe de Traceur à TypeScript, mais cette limitation de TypeScript empêchera que cela se produise. Lorsque TypeScript dit qu'il vise à être un sur-ensemble d'ES6, je pense que cela doit inclure la possibilité de cibler les navigateurs ES5 pour toutes les fonctionnalités ES6 qu'il prend en charge.

Je suppose que je pourrais utiliser TypeScript pour cibler ES6, puis exécuter cette sortie via Traceur ou Babel. Je ne veux vraiment pas avoir à faire ça.

En tant que mise à jour pour ce problème, le protocole itérateur est désormais pris en charge pour la cible ES3 / ES5 à l'aide de --downlevelIteration . Voir # 12346 pour plus d'informations.

Il semble que cela soit censé être corrigé pour TS 2.3, mais j'utilise TS 2.3.3 et

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

observationPointsList est un ObservationPointModel[] , donne:

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

Est-ce que je manque quelque chose?

Ah, en effet. Je ne peux pas voir dans cette documentation ou # 12346 - pourquoi est-ce caché derrière une option par opposition au comportement standard? Cela restera-t-il toujours facultatif?

@lhunath c'est dans les informations de version officielle de la version 2.3 . Elle est facultative car elle a un impact très significatif sur la taille du code généré, et potentiellement sur les performances, pour toutes les utilisations d'itérables (y compris les tableaux). Je trouve que le compromis vaut la peine d'être plus expressif, mais rendre le code existant plus lent et plus complexe semble être une justification raisonnable de l'existence d'un drapeau.

Cette page vous a été utile?
0 / 5 - 0 notes