可选链判断0值属性失效,TypeScript下如何正确检测?
问题描述
我编写了如下代码:
if (action?.notificationKey && state.notifications[action.notificationKey]) { delete state.notifications[action.notificationKey]; }
但这段代码无法满足需求,因为当action.notificationKey的值为0时,可选链的判断条件不成立(0在布尔判断中被视为假值)。我将代码重构为:
if ("notificationKey" in action && state.notifications[action.notificationKey]) { delete state.notifications[action.notificationKey]; }
但这不符合TypeScript要求,第二个条件被标记为“TS2538: Type 'undefined' cannot be used as an index type”错误。请问还有什么方法可以检测可能为0值的属性是否存在?
(注:已修改问题,补充了当前使用的可选链代码)
解决方案
方案1:结合存在性检查与类型断言
用"notificationKey" in action确认属性存在后,通过类型断言明确告诉TypeScript该属性的有效值类型,同时排除undefined的情况:
if ( "notificationKey" in action && typeof action.notificationKey !== 'undefined' && state.notifications[action.notificationKey as keyof typeof state.notifications] ) { delete state.notifications[action.notificationKey as keyof typeof state.notifications]; }
如果notificationKey的类型固定为数字(比如number),直接断言为对应索引类型即可消除TS错误。
方案2:用空值合并运算符区分0与undefined
针对0被误判为假值的问题,使用??空值合并运算符保留0,仅在属性不存在或为null/undefined时返回undefined:
const key = action?.notificationKey ?? undefined; if (key !== undefined && state.notifications[key]) { delete state.notifications[key]; }
这种写法既处理了0的场景,又能让TypeScript正确推断key的类型,避免索引类型错误。
方案3:自定义类型守卫函数
如果需要频繁做这类判断,可以封装类型守卫,让TypeScript准确识别包含有效notificationKey的action:
function hasValidNotificationKey(action: unknown): action is { notificationKey: number } { return ( typeof action === 'object' && action !== null && 'notificationKey' in action && typeof (action as { notificationKey?: unknown }).notificationKey === 'number' ); } if (hasValidNotificationKey(action) && state.notifications[action.notificationKey]) { delete state.notifications[action.notificationKey]; }
类型守卫会帮TS明确action的类型,后续使用action.notificationKey时不会再出现类型报错,同时确保值为有效数字(包括0)。
内容的提问来源于stack exchange,提问作者ddominoo
相关产品推荐
相关产品推荐

