如何解决typescript中使用generator无法使用for-of遍历(编译目标es5,使用node直接运行)的问题?
最近刚开始尝试typescript,想自己写个库练练手,当使用到生成器的时候发生了问题:
首先说明一下环境:
- Windows 10 64bit
- node.js 9.8.0
- typescript 2.7.2
- ts-node 5.0.1
若tsc编译目标为es5
编译时报告
test.ts(3,14): error TS2495: Type '{}' is not an array type or a string type.
但仍然生成了编译后的文件。在node中运行该文件的输出表明for-of遍历该生成器失败。
若tsc编译目标为es6
在nodejs中根本无法运行,因为用到了import
。
测试代码
// Generators.ts
import Random from './Random'
export default class Generators {
static *range(a: number, b?: number) {
if(b == undefined) {
[a, b] = [0, a]
}
for(let i = a; i < b; i++) {
yield i
}
}
}
// test.ts
import G from './Generators'
for(let i of G.range(10)) {
console.log(i)
}
看起来仿佛没什么问题。
然而这是编译后的运行结果(node test.js
):
<啥都没有>
没错,啥都没有23333
同样的代码,把import去掉直接在node里声明函数range
并用for-of遍历是没问题的,代码如下:
function *range(a, b) {
if(b == undefined) {
[a, b] = [0, a]
}
for(let i = a; i < b; i++) {
yield i
}
}
for(let i of range(10)) {
console.log(i)
}
输出如下,非常之正常(expected):
0
1
2
3
4
5
6
7
8
9
undefined
于是查看test.js,发现它是这个样子的:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var Generators_1 = require("./Generators");
for (var _i = 0, _a = Generators_1.default.range(10); _i < _a.length; _i++) {
var i = _a[_i];
console.log(i);
}
猜测_a.length === undefined
,导致循环直接退出,于是手动修改test.js
以验证猜想,改成:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var Generators_1 = require("./Generators");
console.log(Generators_1.default.range(10).length)
for (var _i = 0, _a = Generators_1.default.range(10); _i < _a.length; _i++) {
var i = _a[_i];
console.log(i);
}
再次运行(node test.js
),输出结果:
undefined
果然这是一个expected unexpected error。
最后
所以可以说是typescript的问题了吗?还是有什么特别的技巧能解决这个问题?
真·最后
我又在ts-node
的交互界面里执行了这段在node.js
里正常执行的代码:
function *range(a, b) {
if(b == undefined) {
[a, b] = [0, a]
}
for(let i = a; i < b; i++) {
yield i
}
}
for(let i of range(10)) {
console.log(i)
}
发现输出结果也是空的,直到我使用以下命令行参数启动ts-node
:
ts-node -O "{\"target\": \"esnext\"}"
然后再次输入那段代码,这才得到了正确的结果。
真·真·最后
我手贱又试了一下在node.js
中以require的方式导入以es5
为编译目标编译的Generators.js
模块并再次试验:
let G = require('./Generators.js')
for(let i of G.default.range(10)) console.log(i)
输出:
0
1
2
3
4
5
6
7
8
9
undefined
输出十分的正常,毕竟G.default.range(10)
实现了Symbol.iterator
方法。
以上,不知道有没有大佬知道我哪里做错了或者解决的方法,感谢!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论