TypeScript 2.8.3类型必须具有返回迭代器的Symbol.iterator方法

drnojrws  于 2023-01-06  发布在  TypeScript
关注(0)|答案(8)|浏览(638)

我遇到了一个错误,

Type must have a '[Symbol.iterator]()' method that returns an iterator.

它寄希望于分界线:

class Test {
    private async do() {
        const done = [...(await this.test())]; // Here's the error
    }

    private async *test(): AsyncIterableIterator<string> {
        return;
    }
}

我在TypeScript GitHub仓库中发现了一些问题,但似乎都没有帮助。它们都建议在lib中添加新条目。我使用的是es6目标,并添加了esnextdomes2018。这对错误没有任何影响。
我是否错过了更多的lib条目(我怀疑我正在使用的条目是包含所有内容的所有条目),或者我正在使用的代码无效?

esyap4oy

esyap4oy1#

这对我很有帮助。在tsconfig中,添加以下内容:

{
    "compilerOptions": {
        "lib": [
            "es5", "es6", "dom", "dom.iterable"
        ]
    }
}

这是tsconfig在编译代码时知道要导入哪些接口所必需的。
dom.iterable包含了这里提到的所有接口:https://github.com/microsoft/TypeScript/blob/master/lib/lib.dom.iterable.d.ts
也感谢@domlas提到这一点。我已经投票赞成他的评论,使其被视为默认原因。

6ioyuze2

6ioyuze22#

正如我在上面所评论的,不幸的是异步迭代器目前不支持spread操作符,GitHub中的相关问题是tc39/proposal-async-iteration#103
回顾一下那个问题(减去一些无关的东西,比如“你可以这样做,哦,不,你不能,没关系”):
@jedwards1211表示:
阵列排列作业者的支持是否会成为这项建议的一部分?
@domenic回复:
不是这个提案的一部分...另一个提案肯定可以在这里考虑一些新的东西。
我在其他地方也没有看到任何建议(想start one吗?)。无论如何,因为它甚至不是JavaScript ESNext的一部分,所以很可能不会被添加到TypeScript中。
最可行的替代方案是@estus的答案中详述的for await语法。抱歉,我不能提供更多帮助。祝你好运!

zpf6vheq

zpf6vheq3#

不管语法如何,异步生成器函数不是返回生成器的async函数。
正如提案所述,
异步发生器函数与发生器函数类似,但有以下区别:
当被调用时,异步生成器函数返回一个对象,一个异步生成器,它的方法(next、throw和return)返回{ value,done }的承诺,而不是直接返回{ value,done }。这自动使返回的异步生成器对象成为异步迭代器。
它返回异步生成器,而不是一个承诺,所以await使用它没有任何好处。
由于异步生成器使用的是Symbol.asyncIterator而不是Symbol.iterator,因此它是不可迭代的迭代器,即不能使用常规ES6方法(Array.fromfor..of、spread syntax等)进行迭代,这就是引入for await..of的原因。
上面的代码应该是:

const values = [];

for await (const value of this.test()) {
  values.push(v);
}

异步迭代器上的迭代可以像常规迭代器一样去糖,区别在于next()返回下一个值的承诺,而不是值本身:

const iterator = this.test();
let next;
       
while ((next = await iterator.next()).done === false) {
  values.push(next.value);
}

由于异步生成器规范是一个建议,因此ES6迭代方法中对异步迭代器的支持可能会发生变化。

esbemjvw

esbemjvw4#

我想如果你把**“this.test()”转换成stringarray,就可以消除这个错误。
我的情况有所不同,但我认为我的解决方案可能会帮助一些开发人员。
我收到的错误消息是:

Type 'Ingredient | Ingredient[]' must have a '[Symbol.iterator]()' 
     method that returns an iterator

我尝试了几种方法,下面的三种都奏效了,其中第一种是最简单的:

6qftjkof

6qftjkof5#

我在Reducer(NgRx)中尝试使用扩展语法(...)时也遇到了同样的错误,您可以看到以下内容:

const _ingresoEgresoReducer = createReducer(initialState, 
    on(setItems, (state, { items }) => ({ ...state,  items: [...items]})), 
    on(unSetItems, state => ({ ...state,  items: []})), 
);

它显示错误“类型”IngresoEgreso“必须具有返回迭代器的”Symbol.iterator“方法。”,部分为[...items]
要解决此问题,我应该更改为

const _ingresoEgresoReducer = createReducer(initialState, 
    on(setItems, (state, { items }) => ({ ...state,  items: [...[items]]})), 
    on(unSetItems, state => ({ ...state,  items: []})), 
);

对我来说很好用。
此解决方案位于https://bobbyhadz.com/blog/typescript-type-object-must-have-symbol-iterator-method

ki0zmccv

ki0zmccv6#

只需将as any[]标记为排列运算符,例如

addTemplateVariable(templateVariable: string) {
    this.patchState((state: CmsState) => ({
      cms: {
        ...state.cms,
        templateVariables: [
          ...state.cms.templateVariables as any[],
          templateVariable
        ]
      }
    }))
  }

我在使用ngrx组件存储时遇到了这个问题

siv3szwd

siv3szwd7#

当我们尝试使用扩展语法(...)解压缩数组中的对象时,会出现错误“Type Object must have a Symbol.iterator method that return a iterator”。若要解决此错误,请将对象 Package 在数组中或更正键入。

就像这样。

const obj = { name: 'James' };

// ⛔️ Error: Type Object must have a '[Symbol.iterator]()'
// method that returns an iterator.ts(2488)
const result = [...obj];

我们尝试使用spread语法将对象的属性直接解包到数组中。

此问题的解决方案取决于您的用例。如果要将对象解包到数组中,请在使用spread语法(...)之前将其 Package 到数组中。

const obj = { name: 'James' };

const result = [...[obj]];

console.log(result); // 👉️ [{name: 'James'}]
kq4fsx7k

kq4fsx7k8#

添加时出错
第一个月
在tsconfig.json中

相关问题