如何让TypeScript实现类似JavaScript的原始值属性存在性判断?
问题
XMLValidator.validate 的返回值类型定义为 true | ValidationError,但实际运行时返回的是原始值 true 或带 err 属性的对象。在 JavaScript 里可以直接通过 result.err 判断 XML 是否有效(利用布尔原始值的对象包装器特性),但 TypeScript 会报错:Property 'err' does not exist on type 'true'。想要写出和 JS 一样简洁的 TS 代码,且需要通用解决方案,不想用 typeof 这类繁琐的类型判断。
通用解决方案
1. 类型断言直接访问
直接用类型断言跳过 TS 的类型检查,写法和 JS 几乎一致:
const result = XMLValidator.validate(xmlContent); if ((result as { err?: any }).err) { // 处理错误逻辑 }
嫌重复写断言麻烦的话,可以封装成工具函数复用:
function getValidationErr(result: true | ValidationError) { return (result as { err?: any }).err; } // 使用时直接调用 const err = getValidationErr(XMLValidator.validate(xmlContent)); if (err) { // 处理错误 }
2. 自定义类型守卫(隐式类型收窄)
定义一次类型守卫函数,让 TS 自动识别返回值类型,后续访问 err 不再报错:
function isValidationError(result: true | ValidationError): result is ValidationError { return typeof result !== 'boolean'; } // 使用示例 const result = XMLValidator.validate(xmlContent); if (isValidationError(result)) { // TS 自动推断 result 为 ValidationError,可直接访问 err console.log(result.err); }
这种方式只需定义一次守卫,后续使用逻辑简洁,还能保留 TS 的类型校验能力。
3. 修改返回值类型定义(最彻底)
如果有权修改 XMLValidator 的类型声明,可以把返回值类型改成贴合实际运行时的结构:
// 重新定义返回值类型 type ValidationResult = true | { err: string /* 替换为实际错误类型 */ }; // 覆盖原类型声明 declare class XMLValidator { static validate(xml: string): ValidationResult; }
修改后直接用 result?.err 就能正常判断,完全和 JS 写法一致,TS 也能正确做类型推断。
4. 可选链配合类型断言简化判断
利用 TS 支持的可选链 ?.,搭配一次类型断言快速实现判断:
const err = (XMLValidator.validate(xmlContent) as any)?.err; if (err) { // 处理错误 }
内容的提问来源于stack exchange,提问作者Qiulang
相关产品推荐
相关产品推荐

