对象属性类型收窄:点语法与对象字面量为何表现不同?
为什么TypeScript中两种赋值方式的类型收窄行为不一样?
这本质是TypeScript对实例属性的实时赋值和变量的类型匹配两种场景的处理逻辑不同:
第一种场景(
obj1.x = 1):
obj1已经被初始化为一个MyObj实例,之后直接给这个实例的x属性赋值number类型的值。TypeScript会跟踪这个具体实例的属性变化,做实例级的类型收窄——它明确知道这个特定的obj1实例的x现在就是number,所以后续访问obj1.x时类型会被收窄为number。第二种场景(
obj2 = {x:1}):
obj2的声明类型是MyObj,当你把字面量{x:1}赋值给它时,TypeScript会严格按照你声明的MyObj类型来约束obj2,而不是把obj2的类型收窄成{x:number}。因为MyObj定义里x是可选的number|string,TypeScript默认认为你后续可能会修改obj2的x属性(比如改成string或者undefined),所以不会把obj2.x的类型固定成number,仍然保持原声明的number|string|undefined。
如果想让第二种场景也实现类型收窄,可以用这两种方式:
// 方式1:不指定MyObj,让TypeScript自动推断变量类型 let obj2 = { x: 1 }; obj2.x // number // 方式2:用`as const`断言字面量类型不可变 let obj2: MyObj = { x: 1 } as const; obj2.x // number
内容的提问来源于stack exchange,提问作者jsnerves
相关产品推荐
相关产品推荐

