javascript - Typescript, 'NodeListOf' no es un tipo de arreglo ni un tipo de cadena
Convirtiendo mi JS a modo estricto de TS.
La siguiente sintaxis me parece correcta, pero TS está dando un error en el bucle for sobre allSubMenus con:
[ts] Type 'NodeListOf<Element>' is not an array type or a string type.
¿Qué me estoy perdiendo?
function subAct(target:Node){
const allSubMenus : NodeListOf<Element> = document.querySelectorAll('.subMenuItems')
for (const sub of allSubMenus){
sub.classList.remove('active')
}
}
Respuesta #1
Necesitas configurar la opción del compilador target a es6 o superior para que NodeListOf<T> sea iterable.
Respuesta #2
Según su compilador de destino de TypeScript, puede ocurrir un error de análisis.
El bucle for-of, introducido en la sexta edición de EcmaScript (ES6). Por lo tanto, el motor de JS de los navegadores antiguos no puede entender la sintaxis del bucle for-of. https://hacks.mozilla.org/2015/04/es6-in-depth-iterators-and-the-for-of-loop/
Para resolver este problema,
si solo admites los navegadores modernos más recientes (>=ES6)
cambia tu objetivo de TS
//tsconfig.json
{
"compilerOptions": {
"target": "es6" //above es6 like ES2015,ES2018 ...
}
}
si admites navegadores antiguos (<=ES5)
Presumo que estás usando el siguiente entorno.
//.tsconfig.json
{
"compilerOptions": {
"target": "es5"
}
}
- Para mantener el bucle for-of, usa la sintaxis as any
Nota: "as any" convertirá collection(Objects) a un arreglo y esto afectará algunas características de tipo dentro del alcance de "for".
//.ts
const allSubMenus : NodeListOf<SpecifiedElement> = document.querySelectorAll('.subMenuItems')
for (const sub of allSubMenus as any){ // then will pass compiler
sub.classList.remove('active')
}
El script TS anterior se compilará a
//.js output
var allSubMenus = document.querySelectorAll('.subMenuItems');
for (var _a = 0, _b = forms; _a < _b.length; _a++) {
var sub = _b[_a];
sub.classList.remove('active');
}
https://stackblitz.com/edit/node-ywn1bq?file=main.js
- Usa la sintaxis clásica de bucle for
const allSubMenus : NodeListOf<SpecifiedElement> = document.querySelectorAll('.subMenuItems')
for (let i = 0; i < allSubMenus.length; i++) {
allSubMenus[i].classList.remove('active');
}
<Elemento>
Además de lo anterior, para evitar la siguiente advertencia,
Property '<property name>' does not exist on type 'Element'
puede especificar <Elemento> si conoce el tipo de elemento y existe la definición de tipo.
//for example,
NodeListOf<Element> => NodeListOf<HTMLFormElement>
Historia de ECMAScript (ES)
https://codeburst.io/javascript-wtf-is-es6-es8-es-2017-ecmascript-dca859e4821c
