Búsqueda de sitios web

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; }
    }
}

Artículos relacionados