打字稿 Symbol.iterator
Posted
技术标签:
【中文标题】打字稿 Symbol.iterator【英文标题】:typescript Symbol.iterator 【发布时间】:2018-07-13 09:39:04 【问题描述】:我正在尝试创建一个自定义迭代。
这是我的代码的简化示例:
class SortedArray
*[Symbol.iterator]()
yield 1;
yield 2;
yield 3;
return 4;
const testingIterables = new SortedArray();
for(let item of testingIterables as any) // i have to cast it as any or it won't compile
console.log(item);
此代码将在 ES6 上正确运行,但使用 TypeScript 它将编译并且不打印可迭代值。
这是 TypeScript 中的错误还是我遗漏了什么?
谢谢
【问题讨论】:
除了马达拉的回答之外,还有一个使用--downlevelIteration flag的选项。 【参考方案1】:这不是错误。这取决于你的目标。
TypeScript 做出了一个(在我看来是可怕的)设计决定,如果你将 TS for..of
转换为 ES5 或 ES3,它会发出一个正常的 for (var i; i < testingIterables.length; i++)
循环。
因此,对于目标 ES5 和 ES3,for..of
循环中只允许使用数组和字符串。
有几种方法可以解决这个问题:
如果你的 TypeScript 超过 2.3,你可以将downlevelIteration
标志设置为 true,这将导致 TypeScript 正确编译迭代器,但这意味着你必须在运行时有一个 Symbol.iterator polyfill 来支持不支持的浏览器,否则这些浏览器可能会在意想不到的地方出现运行时错误。
选择更高的目标,ES2015 或更高版本可以工作。然后,您可以使用 Babel 进一步向下转换(您还需要运行时 polyfill 才能使符号工作)
使用while
自己解包迭代器并调用testingIterables.next()
。
【讨论】:
非常感谢。看来您是正确的,现在一切正常。在我看来,我仍然认为这是一个错误。我们必须将我们的代码编译为 ES5 和一种声称是 javascript 超集的语言,如果它迫使我们采用在 ES6 上运行良好的代码并使用 babel 或自己解包,那么这不是程序员所期望的行为。你不同意吗? 似乎 TypeScript 有一个编译器标志:downlevelIteration
自 TS2.3 起,当设置为 true
时,它将假定您有一个用于 Symbol.iterator
的 polyfill 并按预期工作。我会将此添加到我的答案中。
谢谢,这很清楚为什么更改目标会突然导致出现与正确实现迭代器接口的类相关的TS2489: An iterator must have a 'next()' method
错误。以上是关于打字稿 Symbol.iterator的主要内容,如果未能解决你的问题,请参考以下文章