添加多个选择器后TypeScript报错的原因及解决方法
问题:添加选择器后出现TypeScript类型不匹配错误
错误原因
原函数中,当选择器仅为button时,TypeScript能推断document.querySelectorAll('button')返回的是NodeListOf<HTMLButtonElement>,而HTMLButtonElement是HTMLElement的子类,因此转换为数组后类型是HTMLElement[],和函数返回类型匹配。
但当选择器改为a, button时,TypeScript无法确定每个元素具体是HTMLAnchorElement还是HTMLButtonElement,只能将返回值推断为最宽泛的NodeListOf<Element>。Element是HTMLElement的父类,父类数组不能直接赋值给子类数组,因此抛出类型不匹配的错误。
解决办法
方法1:给querySelectorAll指定HTMLElement泛型
明确告诉TypeScript选择器匹配的元素都是HTMLElement:
function findElementsByText(text: string): HTMLElement[] { const selectors = 'a, button' const pattern = new RegExp(text === '' ? '^$' : text) return Array.from(document.querySelectorAll<HTMLElement>(selectors)).filter( (element) => element.innerText.match(pattern) ) }
方法2:使用类型谓词过滤元素
在过滤回调中通过类型谓词断言符合条件的元素是HTMLElement:
function findElementsByText(text: string): HTMLElement[] { const selectors = 'a, button' const pattern = new RegExp(text === '' ? '^$' : text) return Array.from(document.querySelectorAll(selectors)).filter( (element): element is HTMLElement => element.innerText.match(pattern) ) }
方法3:调整函数返回类型(不推荐,除非业务允许)
如果不需要使用HTMLElement的专属属性,可以将函数返回类型改为Element[],直接消除类型不匹配:
function findElementsByText(text: string): Element[] { const selectors = 'a, button' const pattern = new RegExp(text === '' ? '^$' : text) return Array.from(document.querySelectorAll(selectors)).filter( (element) => element.innerText.match(pattern) ) }
内容的提问来源于stack exchange,提问作者wyc
相关产品推荐
相关产品推荐

