是否有一种简洁的功能方式来断言集合中的元素类型?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了是否有一种简洁的功能方式来断言集合中的元素类型?相关的知识,希望对你有一定的参考价值。

假设我们想要收集页面上所有复选框的名称。

最天真的解决方案是

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);

这是最安全但最丑陋的。

最后,我的问题是:有没有办法让它像最新的选项一样安全,但更具可读性?

答案

您可以使用带有filter的类型保护来过滤掉不需要的节点并更改数组的类型:

const names = [...document.querySelectorAll('input[type=checkbox]')]
    .filter((el): el is HTMLInputElement => el instanceof HTMLInputElement)
    .map(el => el.name);

以上是关于是否有一种简洁的功能方式来断言集合中的元素类型?的主要内容,如果未能解决你的问题,请参考以下文章

是否有一种更简洁的 Dapper 方法来仅更新随 Dapper 更改的列?

是否有一种 OCP 友好的方式来动态选择 DbContext 中要访问的集合?

是否有一种较少冗余的方式来加载/保存实体?

是否有一种更简洁的方法可以在 c++(11) 中复制具有多类型值的 unordered_map

Java的Stream操作详解

Apex 中的自定义迭代器