TypeScript中如何无需临时变量使用element.hasAttribute()做校验?
TypeScript中简化元素属性获取与校验的方案
在JavaScript中,我们通常这样获取元素属性:
let myAttr; if (myElem.hasAttribute('my-attribute')) { myAttr = myElem.getAttribute('my-attribute'); }
但在TypeScript里,类型系统仅识别hasAttribute返回boolean、getAttribute返回string | null,无法通过hasAttribute的校验让TypeScript确信getAttribute一定会返回string。
我们需要一种无需临时变量、避免多属性检查时代码冗余的实现方式,替代下面这种冗余写法:
let myAttr: string; let myAttr1 = myElem.getAttribute('my-attribute'); let myAttr2 = myElem.getAttribute('my-attribute-2'); if (typeof myAttr1 === 'string') myAttr = myAttr1; else if (typeof myAttr2 === 'string') myAttr = myAttr2;
1. 自定义类型守卫函数
封装类型守卫,把hasAttribute和getAttribute的逻辑绑定,让TypeScript正确推断类型:
function hasAttributeWithValue(elem: Element, attrName: string): boolean { return elem.hasAttribute(attrName); } // 使用方式 let myAttr: string; if (hasAttributeWithValue(myElem, 'my-attribute')) { // 这里可安全使用非空断言,因为类型守卫已经验证过属性存在 myAttr = myElem.getAttribute('my-attribute')!; }
或者直接封装一个返回确定值的函数:
function getExistingAttribute(elem: Element, attrName: string): string | undefined { return elem.hasAttribute(attrName) ? elem.getAttribute(attrName)! : undefined; } // 使用方式 const myAttr = getExistingAttribute(myElem, 'my-attribute') ?? getExistingAttribute(myElem, 'my-attribute-2');
2. 多属性取值的极简写法
利用可选链和空值合并运算符,直接从多个属性中取第一个有效值,无需临时变量:
const myAttr = myElem.getAttribute('my-attribute') ?? myElem.getAttribute('my-attribute-2') ?? '默认值'; // 不需要默认值的话,可根据业务逻辑处理空值情况
TypeScript会自动推断myAttr的类型为string,因为空值合并后的结果不会是null。
3. 使用断言函数约束类型
通过断言函数强制TypeScript在属性存在时,将getAttribute的返回值推断为string:
function assertAttributeExists(elem: Element, attrName: string): asserts elem has { getAttribute: (name: typeof attrName) => string } { if (!elem.hasAttribute(attrName)) { throw new Error(`元素缺少属性 ${attrName}`); } } // 使用方式 assertAttributeExists(myElem, 'my-attribute'); const myAttr = myElem.getAttribute('my-attribute'); // 此处类型自动推断为string
内容的提问来源于stack exchange,提问作者Drakinite
相关产品推荐
相关产品推荐

