简体   繁体   English

Typescript,'NodeListOf<element> ' 不是数组类型或字符串类型</element>

[英]Typescript,'NodeListOf<Element>' is not an array type or a string type

Converting my JS to TS strict mode.将我的 JS 转换为 TS 严格模式。

The following syntax looks fine to me but TS is complaining in the for loop on allSubMenus with:以下语法对我来说看起来不错,但 TS 在allSubMenusfor循环中抱怨:

[ts] Type 'NodeListOf<Element>' is not an array type or a string type.

What am I missing?我错过了什么?

function subAct(target:Node){

  const allSubMenus : NodeListOf<Element> = document.querySelectorAll('.subMenuItems') 

  for (const sub of allSubMenus){
    sub.classList.remove('active')
  }  
}

This is typescript side parse error.这是打字稿侧解析错误。 I had same problem with HTMLCollectionOf我对 HTMLCollectionOf 有同样的问题

make it as any , it works for me让它为已任,它为我工作

  const allSubMenus : NodeListOf<Element> = document.querySelectorAll('.subMenuItems') 

  for (const sub of allSubMenus as any){ // then will pass compiler
    sub.classList.remove('active')
  }  

您需要将target编译器选项设置为es6或更高版本,以便NodeListOf<T>可迭代。

You could try你可以试试

const allSubMenus : NodeListOf<Element> = document.querySelectorAll('.subMenuItems') 
Array.from(allSubMenus, subMenu => {/* */})

Set "downlevelIteration": true in compilerOptions in your tsconfig.json file.tsconfig.json文件的 compilerOptions 中设置"downlevelIteration": true

From https://www.typescriptlang.org/tsconfig#downlevelIteration来自https://www.typescriptlang.org/tsconfig#downlevelIteration

Downleveling is TypeScript's term for transpiling to an older version of JavaScript. Downleveling 是 TypeScript 的术语,用于转换为旧版本的 JavaScript。 This flag is to enable support for a more accurate implementation of how modern JavaScript iterates through new concepts in older JavaScript runtimes此标志是为了支持更准确地实现现代 JavaScript 如何迭代旧 JavaScript 运行时中的新概念

You can iterate over a NodeListOf with the forEach method.您可以使用forEach方法迭代NodeListOf

const allSubMenus : NodeListOf<Element> = document.querySelectorAll('.subMenuItems') 
allSubMenus.forEach(sub => sub.classList.remove('active'))

Source: https://microsoft.github.io/PowerBI-JavaScript/interfaces/_node_modules_typedoc_node_modules_typescript_lib_lib_dom_d_.nodelistof.html#foreach来源: https : //microsoft.github.io/PowerBI-JavaScript/interfaces/_node_modules_typedoc_node_modules_typescript_lib_lib_dom_d_.nodelistof.html#foreach

while compiling your code you may choose target: ES2017 or target: ES2015 .在编译代码时,您可以选择target: ES2017target: ES2015 also you can set this property in tsconfig.json file unser compilerOptions .您也可以在tsconfig.json文件 unser compilerOptions设置此属性。

So here is the command line code for that:所以这是它的命令行代码:

npx tsc path/to/file.ts --target ES2015

TIP: if you are using babel along side with typescript, it is totally recommended that you always make typescript to compile to latest version of Javascript, and then let babel handles rest of transpiring process.提示:如果您将 babel 与 typescript 一起使用,则完全建议您始终将 typescript 编译为最新版本的 Javascript,然后让 babel 处理其余的过程。 With this technique you add another lever of assurance of supportive level to older browsers since typescript is not ok to compile the code that would run in for example ie6;使用这种技术,您可以为旧浏览器添加另一个支持级别的保证,因为 typescript 无法编译将在例如 ie6 中运行的代码; so babel comes to rescue here and make you yo make sure that your js code would run in even ie < 9 with it's helpful polyfills and other mechanisms that it takes to work!所以 babel 来拯救这里,让你确保你的js代码甚至可以在 ie < 9 中运行,它有帮助的 polyfills 和其他需要工作的机制!

So keep in mind that:所以请记住:

Always let typescript compiles your code to latest javascript ( by setting target: ES2017 ) and let babel transpiles your js code to support older browsers ( separate concerns properly and let each one does the related job).始终让 typescript 将您的代码编译为最新的 javascript(通过设置target: ES2017 )并让 babel 转译您的 js 代码以支持旧浏览器(正确分离关注点并让每个人完成相关工作)。

This assumes you want to keep ES5 target (if not, upgrading it to ES6 will solve the issue as well).这假设您想要保留 ES5 目标(如果没有,将其升级到 ES6 也将解决该问题)。

  1. Use for loop使用for循环
function subAct(target:Node){
  const allSubMenus = document.querySelectorAll('.subMenuItems');

  for (let i = 0; i < allSubMenus.length; i += 1){
    const sub = allSubMenus[i];
    sub.classList.remove('active')
  }  
}
  1. Use Array.from使用Array.from

In order to use this, you have to add ES2015.core to compilerOptions.lib and add polyfill for Array.prototype.from Note that this will loop on the collection twice - the first method is better.为了使用它,您必须将ES2015.core添加到compilerOptions.lib并为Array.prototype.from添加 polyfill 请注意,这将在集合上循环两次 - 第一种方法更好。

function subAct(target:Node){
  const allSubMenus = Array.from(document.querySelectorAll('.subMenuItems'));

  for (const sub of allSubMenus){
    sub.classList.remove('active')
  }  
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 当我尝试将打字稿代码编译为javascript时,得到** Type&#39;NodeListOf <Element> &#39;不是数组类型或字符串类型** - When i try to compile typescript code into javascript, getting **Type 'NodeListOf<Element>' is not an array type or a string type** 输入&#39;NodeListOf <HTMLLIElement> &#39;不可分配给&#39;Element []&#39;类型 - type 'NodeListOf<HTMLLIElement>' is not assignable to type 'Element[]' 类型“NodeListOf”上不存在属性“removeChild”<element> '</element> - Property 'removeChild' does not exist on type 'NodeListOf<Element>' 附加childnode时,在类型&#39;NodeListOf&#39;上不存在其抛出错误“ Property&#39;appendChild&#39; <Element> &#39;。” - When appending childnode, its throwing error “Property 'appendChild' does not exist on type 'NodeListOf<Element>'.” Typescript - 使用数组参数中的元素作为返回类型 - Typescript - Use element in array argument as return type Typescript:从数组联合创建字符串类型 - Typescript: Create string type from Union of Array Typescript 类型“字符串”不可分配给类型 - Typescript Type 'string' is not assignable to type 循环数组返回字符串类型的元素,而不是数组的类型 - Loop array returns element of type string instead of array's type Typescript:字符串可分配给 {} 类型 - Typescript: string is assignable to {} Type 打字稿多维数组类型 - Typescript multidimensional array type
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM