对象属性类型缩小:点与对象文字?

问题描述 投票:0回答:1

我注意到,通过赋值缩小类型的工作方式有所不同,具体取决于我们使用的语法:点表示法或对象文字表示法。这是为什么?这是两个例子。

type MyObj = { x?: number | string }

let obj1: MyObj = {}
obj1.x = 1 // assign x with dot
obj1.x // number

let obj2: MyObj;
obj2 = { x: 1 }; // assign x with object literal
obj2.x // number | string | undefind

我预计在这两种情况下会有相同的行为。

typescript
1个回答
0
投票

工会范围缩小。在第一个示例中,您直接分配给属性

x
,它是联合类型
number | string | undefined
,因此控制流将其范围缩小到
number
的其余范围。但在第二个示例中,您分配给一个不是联合的对象,因此控制流不会缩小它的范围。

缩小也仅发生在当前范围内,例如,您将在嵌套函数中失去它。

我明白了,似乎 TS 可以解决这个问题,但遗憾的是它没有,至少目前,他们不断改进控制流分析。

如果将类型更改为联合,则分配文字对象将缩小范围:

type MyObj = { x?: number | string }

let obj1: MyObj = {}
obj1.x = 1 // assign x with dot
obj1.x // number

function anotherScope() {
    obj1.x // number | string | undefind
}

let obj2: MyObj;
obj2 = { x: 1 }; // assign x with object literal
obj2.x // number | string | undefind

obj2.x = 2;
obj2.x // number

let obj3: { x: number  } | { x: string } | { x?: undefined };
obj3 = { x: 1 } ; // assign x with object literal
obj3.x // number, narrowed to first member of the union


let obj4: { x?: number  } | { x?: string } 
obj4 = { x: 1 } ; // assign x with object literal
obj4.x // number | undefind, narrowed to first member of the union

游乐场

© www.soinside.com 2019 - 2024. All rights reserved.