【问题标题】:Typescript array.from(iterator) incorrect type and cannot be cast?Typescript array.from(iterator) 类型不正确,不能强制转换?
【发布时间】:2020-08-04 08:29:48
【问题描述】:

在将流代码转换为打字稿时,使用迭代器时会发生错误。迭代器缺少一些东西

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

typescript 的编译目标是“es6”,所以应该完全支持映射?还是不可能从迭代器创建一个数组,而我做错了(而且 babel 就是那么宽容)?

【问题讨论】:

    标签: arrays typescript iterator


    【解决方案1】:

    您可能知道,iterator 是一个带有 next 方法的对象,用于迭代 iterable(带有 [Symbol.iterator] 方法的对象,用于获取一个迭代器)。

    Array.from 接受一个 iterable(或类似数组),但在该代码中它认为它只是获得一个 iterator

    大多数迭代器,包括您从标准 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 会推断它们。)

    Here's a version 在操场上使用Iterator 演示问题。

    Here's that same code 使用 Iterator&lt;T&gt; &amp; Iterable&lt;T&gt; 如上所述。

    【讨论】:

    • FWIW,我在几个月后出版的新书的第 6 章中详细介绍了迭代器和可迭代对象。如果您有兴趣,请查看我的个人资料了解详情。
    • 如果我检查 javascript map.values() 中的代码 确实 返回一个带有 next() 的对象:完全是一个迭代器。编辑:好的,现在我删除了所有类型信息,我注意到打字稿自动分配它IterableIterator 类型。提出一个问题,是否有任何迭代器本身不可迭代?
    • @paul23 - 是的,我刚刚意识到——你在我认为是Map 上使用values,它返回一个(可迭代的)迭代器。但是Array.from 被定义为采用iterable,而不是iterator。同样,大多数迭代器(包括您从内置 JavaScript 函数中获得的所有迭代器)也是 iterable 的,但并非全部都是。所以你可能想调整routes的返回类型,我会更新答案。
    • @paul23 - 现在修复它,很抱歉在第一遍时错过了values 的东西(尽管已经复制了它!)。 :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多