Ответ 1
Вместо 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.keys()) {
console.log(key);
}
И я получаю сообщение об ошибке:
Тип 'IterableIteratorShim & lt; [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 и машинописный текст 1.8.10, и моя цель - es5. У кого-нибудь была эта проблема?
Вместо Map.prototype.forEach((value, key, map) => void, thisArg?) : void
можно использовать
Используйте его следующим образом:
myMap.forEach((value: boolean, key: string) => {
console.log(key, value);
});
Просто используйте метод Array.from(), чтобы преобразовать его в массив:
myMap : Map<string, boolean>;
for(let key of Array.from( myMap.keys()) ) {
console.log(key);
}
Используя Array.from, Array.prototype.forEach() и функции стрелок:
Итерации по клавишам:
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 в --downlevelIteration
"Новый --downlevelIteration
":
for..of statements
, Array Destructuring и Spread в массивах Array, Call и New используются Symbol.iterator в ES5/E3, если они доступны при использовании--downlevelIteration
По умолчанию это отключено! Добавьте "downlevelIteration": true
для вашего tsconfig.json
или --downlevelIteration
флаг --downlevelIteration
в tsc
, чтобы получить полную поддержку итератора.
При этом вы можете писать for (let keyval of myMap) {...}
и keyval
type будут автоматически выведены.
Почему это отключено по умолчанию? Согласно составителю TypeScript @aluanhaddad,
Это необязательно, поскольку оно оказывает существенное влияние на размер сгенерированного кода и потенциально на производительность для всех применений итераций (включая массивы).
Если вы можете настроить таргетинг на ES2015 ("target": "es2015"
в tsconfig.json
или tsc --target ES2015
) или более поздней 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];
}
for (let [key, value] of map) {
console.log(key, value);
}
Я использую последние TS и node (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]);
});
Простое объяснение, чтобы сделать это из HTML, если у вас есть карта типов (ключ, массив):
Я инициализирую массив таким образом:
public cityShop: Map<string, Shop[]> = new Map();
И для перебора над ним я создаю массив из значений ключа: - просто используйте его как массив с помощью: keys = Array.from(this.cityShop.keys());
Затем, в HTML, я могу использовать:
*ngFor="let key of keys"
Внутри этого кучка я просто получаю значение массива с помощью this.cityShop.get(key)
И... сделано!
Если вам не нравятся вложенные функции, вы также можете перебирать ключи:
myMap : Map<string, boolean>;
for(let key of myMap) {
if (myMap.hasOwnProperty(key)) {
console.log(JSON.stringify({key: key, value: myMap[key]}));
}
}
Обратите внимание, что вы должны отфильтровать инертные ключи без ключа с помощью hasOwnProperty
, если вы этого не сделаете, вы получите предупреждение или ошибку.