bucle for de TypeScript sobre HTMLCollection
Quiero iterar sobre los resultados de
document.getElementsByTagName("...");
Devuelve un HTMLCollection, no un arreglo. Así que no puedo simplemente usar forEach. Lo siguiente es posible pero no se ve muy bien:
let elements = document.getElementsByTagName("...");
for (var i = 0, m = elements.length; i < m; i++) {
let element = elements[i];
}
Para JavaScript, existe prácticamente la misma pregunta: Bucle for para elementos de HTMLCollection
Y aparentemente, con las últimas actualizaciones, los navegadores modernos soportan:
var list = document.getElementsByClassName("events");
for (let item of list) {
log(item.id);
}
Pero el compilador de TypeScript se queja:
error TS2495: Type 'NodeListOf<HTMLParagraphElement>' is not an array type or a string type.
Sin embargo, todavía se transpila a Javascript adecuado. Incluso es consciente de lo que estoy haciendo aquí y no solo copia el código fuente. La salida compilada es esta:
var elements = main_div.getElementsByTagName("p");
for (var _i = 0, elements_1 = elements; _i < elements_1.length; _i++) {
var element = elements_1[_i];
}
Esto es genial, ya que el código generado será compatible incluso en navegadores antiguos. Pero me gustaría deshacerme del mensaje de error.
Mis opciones de compilador son estas:
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"sourceMap": true,
"rootDir": "src",
"lib": [
"es2015",
"dom"
]
}
}
Intenté editar las opciones de mi biblioteca. Esta característica específica era parte de ES6 y se ha reformulado varias veces. Así que probé las diversas versiones de ecmascript en lib pero no pude encontrar una configuración que funcionara.
Respuesta #1
Puedes convertirlo en un arreglo si quieres usar forEach
const elements: Element[] = Array.from(document.getElementsByTagName("..."));
elements.forEach((el: Element) => {
// do something
})
Respuesta #2
El compilador de TypeScript admite esto después de especificar una bandera adicional, downlevelIteration:
{
"compilerOptions": {
"target": "es5",
"downlevelIteration": true
}
}
Sin embargo, esto no solo eliminará el error, sino que también cambiará la salida del compilador. Este TypeScript de entrada:
function compileTest(){
let elements = document.getElementsByTagName("p");
for(let element of elements){
console.log(element);
}
}
se compila a este JavaScript:
function compileTest() {
var e_1, _a;
var elements = document.getElementsByTagName("p");
try {
for (var elements_1 = __values(elements), elements_1_1 = elements_1.next(); !elements_1_1.done; elements_1_1 = elements_1.next()) {
var element = elements_1_1.value;
console.log(element);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (elements_1_1 && !elements_1_1.done && (_a = elements_1.return)) _a.call(elements_1);
}
finally { if (e_1) throw e_1.error; }
}
}
