TypeScript使用Cheerio报错Property 'attribs'不存在于Element类型如何解决?
报错原因
Cheerio 的 Element 是包含 TagElement、文本节点、注释节点的联合类型,只有 TagElement 具备 attribs 属性,TS 无法确定你遍历到的 element 一定是标签节点,因此触发类型报错。
修复方案
方案1:使用类型守卫收窄类型(推荐,符合TS类型安全规范)
用 Cheerio 内置的 isTag 方法做类型判断,通过后 TS 会自动将 element 的类型收窄为 TagElement,就可以正常访问 attribs:
import { load, isTag } from 'cheerio'; const $ = load(response.body), selection = $('td:nth-child(1) .spaceit_pad'), filteredNodes = []; selection.toArray().map((element) => { // 非标签节点直接跳过 if (!isTag(element)) return; const attr = element.attribs; if (attr.class.split(' ').length === 1) { filteredNodes.push(element); console.log(typeof element); } });
方案2:类型断言(适合确定节点类型的场景)
如果你可以100%确认当前选择器返回的所有节点都是标签节点,没有其他类型节点,可以直接用类型断言覆盖TS的默认推断:
selection.toArray().map((element) => { // 手动断言为TagElement类型 const attr = (element as cheerio.TagElement).attribs; if (attr.class.split(' ').length === 1) { filteredNodes.push(element); console.log(typeof element); } });
方案3:使用Cheerio封装的属性API
直接用Cheerio封装的attr()方法获取属性,不需要直接操作底层节点属性,天然规避类型问题:
selection.toArray().map((element) => { const classVal = $(element).attr('class'); // 先判断class存在再做后续处理 if (classVal && classVal.split(' ').length === 1) { filteredNodes.push(element); console.log(typeof element); } });
内容的提问来源于stack exchange,提问作者TheWhiteFang
相关产品推荐
相关产品推荐

