为何TypeScript中需要使用非空断言运算符"!"?
TypeScript可选属性类型守卫失效问题解析
问题场景
先定义一个包含可选键c的接口:
interface MyInterface { a: number; b: number; c?: number; } const obj: MyInterface = { a: 0, b: 0, }; const keys: Array<keyof MyInterface> = ['a', 'b', 'c']
触发的类型错误
即便提前检查了obj[key]不为undefined,下面的代码依然会抛出类型错误:Object is possibly 'undefined'.
const res = keys.some((key) => (obj[key] !== undefined && obj[key] > 0))
无效的尝试:检查key是否存在
有人尝试通过判断key是否存在来解决,但显然key本身都是已定义的,这种方法完全无效:
const res = keys.some((key) => (key && obj[key] !== undefined && obj[key] > 0))
可行解决方案:使用非空断言!
添加非空断言运算符!可以解决这个类型错误:
const res = keys.some((key) => (obj[key] !== undefined && obj[key]! > 0))
问题原因
TypeScript的类型系统无法在这个场景下完成类型窄化:
key的类型是联合类型"a" | "b" | "c",对应obj[key]的类型是number | undefined(因为c是可选属性)。- 虽然我们写了
obj[key] !== undefined的存在性检查,但TypeScript无法将这个检查和key的具体类型关联起来——它没办法判断当前遍历的key到底是必选属性的键还是可选属性的键,因此无法自动把obj[key]的类型从number | undefined窄化为number。 - 非空断言
!相当于手动向TypeScript确认:“我已经确保这个值不是undefined”,从而绕过了类型检查。
内容的提问来源于stack exchange,提问作者Riadh Adrani
相关产品推荐
相关产品推荐

