Typescript array.from (итератор) неверный тип и не может быть приведен? - PullRequest
2 голосов
/ 21 апреля 2020

При преобразовании кода потока в машинописный текст возникает ошибка при использовании итераторов. Итератору чего-то не хватает

const iter: Iterator<RouteData> = contentMap.routes();
const contentArray: Array<RouteData> = Array.from(iter);

. Выдает следующую ошибку: обратите внимание, что это указывает на строку second , поэтому iter имеет правильный тип / возвращение contentMap.routes() такое итератор:

Error:(109, 55) TS2769: No overload matches this call.
  Overload 1 of 4, '(iterable: Iterable<RouteData> | ArrayLike<RouteData>): RouteData[]', gave the following error.
    Argument of type 'Iterator<RouteData, any, undefined>' is not assignable to parameter of type 'Iterable<RouteData> | ArrayLike<RouteData>'.
      Property 'length' is missing in type 'Iterator<RouteData, any, undefined>' but required in type 'ArrayLike<RouteData>'.
  Overload 2 of 4, '(arrayLike: ArrayLike<RouteData>): RouteData[]', gave the following error.
    Argument of type 'Iterator<RouteData, any, undefined>' is not assignable to parameter of type 'ArrayLike<RouteData>'.

Почему это происходит и как мне это исправить?

Итератор создается где-то вроде:

routes():Iterator<RouteData> {
    return this._routes.values();
}

Цель компиляции для машинописного текста это "es6", поэтому карты должны полностью поддерживаться? Или просто невозможно создать массив из итератора, и я все делаю неправильно (и это было просто вежливо)?

1 Ответ

2 голосов
/ 21 апреля 2020

Как вы, вероятно, знаете, итератор - это объект с методом next, используемый для итерации по итерируемому (объект с методом [Symbol.iterator] для получения итератора от него).

Array.from принимает итерируемый (или похожий на массив), но в этом коде он думает, что просто получает итератор .

Большинство итераторов, включая все те, которые вы получаете из стандартных JavaScript методов, также являются итеративными, поскольку они реализуют [Symbol.iterator]() { return this; } прямо или косвенно через прототип итератора, но не все это делают. Поэтому небезопасно предполагать, что все итераторы являются итеративными.

Возможно, вы захотите обновить routes, чтобы показать, что он возвращает что-то, что является итератором и итерируемым:

routes(): Iterator<T> & Iterable<T> {
    return this._routes.values();
}

Тогда:

const iter = contentMap.routes();
const contentArray = Array.from(iter);

(Нет необходимости в явных типах для них, TypeScript выведет их.)

Вот версия на игровой площадке демонстрация проблемы с использованием Iterator.

Вот тот же код с использованием Iterator<T> & Iterable<T>, как указано выше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...