我正在尝试迭代打字稿地图,但我一直收到错误,我找不到任何解决方案,因为这样一个微不足道的问题。
我的代码是:
myMap : Map<string, boolean>;
for(let key of myMap.keys()) {
console.log(key);
}
我得到错误:
类型'IterableIteratorShim <[string,boolean]>'不是数组类型或字符串类型。
完整堆栈跟踪:
Error: Typescript found the following errors:
/home/project/tmp/broccoli_type_script_compiler-input_base_path-q4GtzHgb.tmp/0/src/app/project/project-data.service.ts (21, 20): Type 'IterableIteratorShim<[string, boolean]>' is not an array type or a string type.
at BroccoliTypeScriptCompiler._doIncrementalBuild (/home/project/node_modules/angular-cli/lib/broccoli/broccoli-typescript.js:115:19)
at BroccoliTypeScriptCompiler.build (/home/project/node_modules/angular-cli/lib/broccoli/broccoli-typescript.js:43:10)
at /home/project/node_modules/broccoli-caching-writer/index.js:152:21
at lib$rsvp$$internal$$tryCatch (/home/project/node_modules/rsvp/dist/rsvp.js:1036:16)
at lib$rsvp$$internal$$invokeCallback (/home/project/node_modules/rsvp/dist/rsvp.js:1048:17)
at lib$rsvp$$internal$$publish (/home/project/node_modules/rsvp/dist/rsvp.js:1019:11)
at lib$rsvp$asap$$flush (/home/project/node_modules/rsvp/dist/rsvp.js:1198:9)
at _combinedTickCallback (internal/process/next_tick.js:67:7)
at process._tickCallback (internal/process/next_tick.js:98:9)
我正在使用angular-cli beta5和typescript 1.8.10,我的目标是es5。有没有人有这个问题?
你可以用Map.prototype.forEach((value, key, map) => void, thisArg?) : void
代替
像这样使用它:
myMap.forEach((value: boolean, key: string) => {
console.log(key, value);
});
如果你不喜欢嵌套函数,你也可以迭代键:
myMap : Map<string, boolean>;
for(let key of myMap) {
if (myMap.hasOwnProperty(key)) {
console.log(JSON.stringify({key: key, value: myMap[key]}));
}
}
注意,您必须使用hasOwnProperty
过滤掉非键迭代,如果不这样做,则会收到警告或错误。
只需使用Array.from()方法将其转换为数组:
myMap : Map<string, boolean>;
for(let key of Array.from( myMap.keys()) ) {
console.log(key);
}
使用Array.from,Array.prototype.forEach()和arrow functions:
迭代键:
Array.from(myMap.keys()).forEach(key => console.log(key));
迭代值:
Array.from(myMap.values()).forEach(value => console.log(value));
迭代条目:
Array.from(myMap.entries()).forEach(entry => console.log('Key: ' + entry[0] + ' Value: ' + entry[1]));
这对我有用。 TypeScript版本:2.8.3
for (const [key, value] of Object.entries(myMap)) {
console.log(key, value);
}
根据TypeScript 2.3 release notes on "New --downlevelIteration
":
数据,调用和新表达式中的
for..of statements
,数组解析和Spread元素在使用--downlevelIteration
时支持ES5 / E3中的Symbol.iterator(如果可用)
默认情况下不启用此功能!将"downlevelIteration": true
添加到您的tsconfig.json
,或将--downlevelIteration
标志传递给tsc
,以获得完整的迭代器支持。
有了这个,你可以写for (let keyval of myMap) {...}
和keyval
的类型将自动推断。
为什么默认关闭?根据TypeScript撰稿人@aluanhaddad,
它是可选的,因为它对迭代器(包括数组)的所有使用对生成的代码的大小以及潜在的性能具有非常显着的影响。
如果您可以针对ES2015("target": "es2015"
或tsconfig.json
中的tsc --target ES2015
)或更高版本,启用downlevelIteration
是明智之举,但如果您的目标是ES5 / ES3,您可以进行基准测试以确保迭代器支持不会影响性能(如果是,你可能会更好地使用Array.from
转换或forEach
或其他一些解决方法)。
for (let entry of Array.from(map.entries())) {
let key = entry[0];
let value = entry[1];
}
我正在使用最新的TS和节点(分别为v2.6和v8.9),我可以这样做:
let myMap = new Map<string, boolean>();
myMap.set("a", true);
for (let [k, v] of myMap) {
console.log(k + "=" + v);
}
这对我有用。
Object.keys(myMap).map( key => {
console.log("key: " + key);
console.log("value: " + myMap[key]);
});
如果您有类型的Map(键,数组),只需从HTML中进行简单的解释即可:
我用这种方式初始化数组:
public cityShop: Map<string, Shop[]> = new Map();
为了迭代它,我从键值创建一个数组: - 只需使用它作为一个数组:keys = Array.from(this.cityShop.keys());
然后,在HTML中,我可以使用:
*ngFor="let key of keys"
在这个bucle中,我只是用this.cityShop.get(key)获取数组值
并做了!