TypeScript逻辑或赋值变量类型推断异常,如何解决mode属性访问报错?
解决TypeScript中
||赋值后类型推断丢失的问题 我完全懂你遇到的这个痛点——TypeScript在处理子类型联合的时候,会自动把CustomNotification | Notification简化成Notification,因为CustomNotification本质是Notification的扩展类型(通过交叉类型实现),这就导致你明明知道notification可能包含mode属性,但TypeScript就是不认。下面给你几个不用重构变量的解决办法:
方法1:用in操作符做类型守卫(最简单直接)
TypeScript支持用in运算符来缩小类型范围,只要检查'mode'属性是否存在,它就会自动推断当前notification是CustomNotification类型:
if ('mode' in notification && notification.mode !== Modes.error) { // 这里TypeScript会正确识别notification为CustomNotification console.log("处理非错误的自定义通知"); }
方法2:自定义类型守卫函数(适合重复判断场景)
如果需要在多个地方判断这个类型,写一个复用的类型守卫函数会更清晰:
// 定义类型守卫函数,告诉TypeScript如何识别CustomNotification function isCustomNotification(n: Notification): n is CustomNotification { return 'mode' in n; } // 使用时 if (isCustomNotification(notification) && notification.mode !== Modes.error) { // 这里n会被推断为CustomNotification // 执行你的逻辑 }
方法3:显式保留联合类型(类型断言)
如果你想强制TypeScript保留CustomNotification | Notification的联合类型,可以用类型断言来避免它自动简化:
// 赋值时显式断言为联合类型 const notification = (customNotification || defaultNotification) as CustomNotification | Notification; // 之后再配合类型守卫使用 if ('mode' in notification && notification.mode !== Modes.error) { // 正常访问mode属性 }
不过要注意,类型断言是你在告诉TypeScript“我比你更清楚这个类型”,所以要确保逻辑上不会出现错误类型的情况。
方法4:用可选链配合非空判断
另一种简单的方式是直接检查mode是否存在,TypeScript会根据这个判断缩小类型:
if (notification.mode !== undefined && notification.mode !== Modes.error) { // 这里TypeScript会知道mode属性存在 }
这种方式适合简单场景,但不如in操作符严谨——如果有其他继承自Notification的类型也有mode属性,可能会出现误判,但在你的当前场景下完全可行。
内容的提问来源于stack exchange,提问作者Khaled
相关产品推荐
相关产品推荐

