Deno TypeScript中为何Node类型不存在getAttribute属性?
解决Deno TypeScript与deno-dom协作的类型错误问题
我将JavaScript代码转为Deno TypeScript模块,用deno-dom抓取页面所有a[href]链接,脚本运行正常,但deno test时报错:TS2339 [ERROR]: Property 'getAttribute' does not exist on type 'Node'。尝试声明Element类型后,又出现两个新错误:
- NodeList无法赋值给Iterable
类型 string | null无法赋值给string
问题根源
- deno-dom的
document.querySelectorAll()返回的是NodeList<Node>,而非浏览器环境中的NodeListOf<Element>,TypeScript因此认定每个元素是Node类型,不具备getAttribute方法 Element.getAttribute()本身可能返回null,转换后的数组元素类型为string | null,后续直接当作string处理会触发类型校验错误
修改后的完整代码
import { DOMParser } from "https://deno.land/x/deno_dom/deno-dom-wasm.ts"; export async function getAllLinks( url: string, slice = 5, ): Promise<{ source: string; links: string[] }> { try { const response = await fetch(url); const content: string = await response.text(); const document = new DOMParser().parseFromString(content, "text/html"); if (document === null) throw new Error("Failed to parse HTML"); const baseUrl = response.url; // 将NodeList转为数组,再过滤出Element类型节点 const linkNodes = Array.from(document.querySelectorAll('a[href^="http:"], a[href^="https:"]')); // 类型守卫:确保节点是Element且存在href属性 const linkElements = linkNodes.filter((node): node is Element => node instanceof Element && node.hasAttribute("href") ); if (linkElements.length === 0) { throw new Error("No links found"); } const links = linkElements .map((link) => link.getAttribute("href")) // 过滤null值,同时通过类型断言确认后续为string类型 .filter((href): href is string => href !== null) .map((link) => { const absoluteURL = new URL(link, baseUrl); return absoluteURL.href; }) .filter((link) => { const parsedUrl = new URL(url); const parsedLink = new URL(link); return parsedUrl.hostname !== parsedLink.hostname; }); return { source: baseUrl, links: links.slice(0, slice), }; } catch (error) { console.error(error); throw error; } }
关键修改说明
- 处理Node与Element类型不匹配:先把
NodeList转为数组,再用类型守卫node is Element过滤出真正的Element节点,让TypeScript确认后续操作的节点具备Element的方法 - 处理null值类型问题:在
map后添加过滤逻辑,既去除getAttribute返回的null值,又通过类型断言让TypeScript确认后续元素都是string类型 - 优化空值判断:用
linkElements.length === 0替代原有的linkSelector === undefined || linkSelector === null,更准确判断是否存在有效链接
内容的提问来源于stack exchange,提问作者T0nic
相关产品推荐
相关产品推荐

