假设我们要收集页面上所有复选框的名称。
最幼稚的解决方案是
const names = [...document.querySelectorAll('input[type=checkbox]')]
.map(el => el.name);
它不会通过类型检查,因为document.querySelectorAll
返回的集合Element
没有name
属性。
一种解决方法是明确指定类型参数document.querySelectorAll<HTMLInputElement>
。
这会让编译器满意,而不是让我满意:现在,这段代码不是安全类型,可能在运行时失败。
一种类型安全的解决方案可能看起来
const names = [...document.querySelectorAll('input')]
.filter(el => el.matches('[type=checkbox]'))
.map(el => el.name);
但是它会使代码更冗长,更不清楚,并且通常该解决方案无法扩展(在这里我是说您不能通用地应用它,因为并非每个选择器都可以轻松拆分)。
最后,它既具有静态检查又具有运行时检查
const names = [...document.querySelectorAll('input[type=checkbox]')]
.reduce((acc, el) => el instanceof HTMLInputElement ? [...acc, el] : acc, [] as HTMLInputElement[])
.map(el => el.name);
这是最安全却最丑陋的
最后,我的问题是:除了让它更具可读性之外,没有其他方法可以使它安全吗?
答案 0 :(得分:3)
您可以在filter
中使用类型防护,以过滤掉不需要的节点并更改数组的类型:
const names = [...document.querySelectorAll('input[type=checkbox]')]
.filter((el): el is HTMLInputElement => el instanceof HTMLInputElement)
.map(el => el.name);