下面是一个例子(不是一个好例子:p):
type RandomType = {x: number, y: number}
type UnifiedTypes = RandomType | 0
type ArrayOfTypes = Array<(RandomType | UnifiedTypes)[]>
const newIns: ArrayOfTypes = [[0, {x: 10, y: 201}], [0, {x: 10, y: 201}]]
for(let i=0; i < newIns.length; ++i){
for(let j=0; j < newIns[i].length; ++j){
if(newIns[i][j] !== 0){
newIns[i][j].x = 30 // Property 'x' does not exist on type 'UnifiedTypes'. Property 'x' does not exist on type '0'
}
}
}
// Hoewever, when outside of loop compiler runs fine
if(newIns[0][0] !== 0) {
newIns[0][0].x = 33; // no error thrown
}
当循环遍历一个联合类型的数组时,缩窄似乎不起作用,所以我有点迷惑。我错过了smt吗?
通过缩小索引元素要保存的类型,类型脚本编译器应该能够计算出指定索引中元素数组的类型,从而安全地进行赋值。
2条答案
按热度按时间ia2d9nvy1#
在我看来,当你输入
newIns[i][j]
时,在这一点上理解为RandomType | UnifiedTypes
。但是当你在循环中检查newIns[i][j] !== 0
时,newIns[i][j]
的类型被缩小为UnifiedTypes
,即RandomType | 0
。但是,当你检查newIns[0][0] !== 0
时,newIns[0][0]
的类型被缩小为RandomType
。所以编译器知道newIns[0][0]
有一个属性x
。换句话说,见下面的例子。如您所知,
items
引用Item
类型,items[i]
被推断为Item
,即Shape | Color
,但是,当您选中items[i] !== 'circle'
时,您将items[i]
的类型缩小为Color
,因为您从联合中排除了它是'circle'
的可能性。你可以像这样解决。
x1米20英寸1x
wz3gfoph2#
如果你为
newIns[i][j]
元素创建一个常量的话,这将是有效的。对她来说,TS将能够正确地处理类型。