TypeScript可选属性类型收窄疑问:赋值常量为何能正确收窄?
TypeScript可选属性的类型收窄问题
问题重现
先看这段代码:
type A = { b?: string | undefined } const a: A = { b: "test" }
明明在if里检查了a.b存在,可条件块里a.b的类型还是string | undefined:
if (a.b) { // 预期是string,实际却是string | undefined a.b }
但把a.b赋值给新常量c后,c的类型就正确变成string了:
if (a.b) { // 类型正确收窄为string const c = a.b }
为什么会这样?
1. 对象属性的可变性限制了类型收窄
TypeScript对对象属性和独立常量的类型跟踪逻辑不一样:
- 哪怕
a是const声明的对象,它的属性还是能被修改的(除非加readonly)。TypeScript得考虑这种可能性——比如在if条件检查完a.b之后,会不会有其他代码把a.b改成undefined?所以它不敢直接把a.b的类型收窄成string。 - 但当你把
a.b赋值给const c的时候,TypeScript知道这个常量一旦赋值就不能改了。既然if (a.b)已经确认此时a.b是非undefined的,那c的类型就可以安全地固定为string。
2. 只读属性的验证
如果给属性加上readonly,TypeScript就能正确收窄属性类型了,因为它确定这个属性不会被修改:
type A = { readonly b?: string | undefined } const a: A = { b: "test" } if (a.b) { // 这里a.b的类型会被正确收窄为string a.b }
内容的提问来源于stack exchange,提问作者endofline
相关产品推荐
相关产品推荐

