Typescript: for..of с итераторами

Созданный на 14 мая 2015  ·  9Комментарии  ·  Источник: microsoft/TypeScript

Было бы неплохо, если бы новый синтаксис for (let value of values) работал с итераторами; то есть:

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

Связанные с № 2695.

Question

Самый полезный комментарий

Меня это действительно разочаровывает. Я могу использовать for-of с любым итеративным и целевым ES5 с Traceur и Babel сегодня. Я заинтересован в том, чтобы предложить нашей команде перейти с Traceur на TypeScript, но это ограничение в TypeScript остановит это. Когда TypeScript заявляет, что он стремится стать надмножеством ES6, я думаю, что необходимо включить возможность нацеливания на браузеры ES5 для всех поддерживаемых им функций ES6.

Все 9 Комментарий

Это уже разрешено, если ваша цель - ES6:

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

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

Причины, по которым это не разрешено в ES5 / ES3:

  • Одна из аксиом TypeScript - не использовать излучение, ориентированное на тип. то есть, генерируемый код не зависит от того, что система типов думает о вашем коде, а скорее как синтаксическое преобразование вашего источника ввода.
  • Выполнение полной эмуляции итератора будет означать, что мы должны зависеть от поллифила для Symbol, опять же, еще одно качество, которое мы хотим сохранить.
  • Сгенерированная логика полной итерации не обманчива, вам нужно вызвать next () и проверить, выполнено ли, если она не верна, если не использовать значение. это дополнительная отправка, два поиска свойств и выделение объекта на каждой итерации цикла. Мы постарались сделать излучаемый код простым и связанным с источником, особенно по характеристикам производительности.
  • Наконец, чтобы сделать все это с настраиваемыми итеративными объектами, нам все равно нужно сделать это с массивами, поскольку массивы не имеют этой поддержки в ES5 / ES3, и мы не хотим делать излучение, ориентированное на тип, нам нужно преобразовать массив в итерацию, которая значительно медленнее, чем ваш обычный цикл for. и основная проблема заключается в том, что, глядя на цикл в массиве, не ясно, что это повлечет за собой такие затраты.

В результате этих факторов в ES3 / ES5 разрешены только массивы в циклах for..of (как наиболее распространенные итерируемые объекты, доступные сегодня в языке JS); что касается нацеливания на ES6 (то есть с поддержкой механизма выполнения для итераций и итерируемых массивов), пользовательские итерации разрешены в дополнение к Array, string, map и set и т. д.

Понял ...
@mhegazy Большое спасибо за развернутый ответ !!!

Меня это действительно разочаровывает. Я могу использовать for-of с любым итеративным и целевым ES5 с Traceur и Babel сегодня. Я заинтересован в том, чтобы предложить нашей команде перейти с Traceur на TypeScript, но это ограничение в TypeScript остановит это. Когда TypeScript заявляет, что он стремится стать надмножеством ES6, я думаю, что необходимо включить возможность нацеливания на браузеры ES5 для всех поддерживаемых им функций ES6.

Думаю, я мог бы использовать TypeScript для таргетинга на ES6, а затем запустить этот вывод через Traceur или Babel. Хотя я действительно не хочу этого делать.

В качестве обновления для этой проблемы протокол итератора теперь поддерживается для целевого ES3 / ES5 с использованием --downlevelIteration . См. # 12346 для получения дополнительной информации.

Похоже, это должно быть исправлено в TS 2.3, но я использую TS 2.3.3 и

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

где observationPointsList - это ObservationPointModel[] , дает:

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

Я что-то упускаю?

Ах, конечно. Я не вижу в этой документации или # 12346 - почему это скрыто за опцией, а не за стандартным поведением? Всегда ли это останется необязательным?

@lhunath находится в официальной информации о выпуске 2.3 . Это необязательно, потому что он оказывает очень значительное влияние на размер сгенерированного кода и, возможно, на производительность для всех видов использования итераций (включая массивы). Я считаю, что этот компромисс стоит большей выразительности, но создание более медленного и сложного кода кажется разумным оправданием наличия флага.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги

Смежные вопросы

seanzer picture seanzer  ·  3Комментарии

manekinekko picture manekinekko  ·  3Комментарии

Antony-Jones picture Antony-Jones  ·  3Комментарии

siddjain picture siddjain  ·  3Комментарии

jbondc picture jbondc  ·  3Комментарии