Búsqueda de sitios web

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"
  }
}
  1. 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

  1. 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

Artículos relacionados