gpt4 book ai didi

typescript - 即使在使用类型保护检查之后也无法缩小对象属性的类型

转载 作者:行者123 更新时间:2023-12-05 04:23:43 24 4
gpt4 key购买 nike

TFlavour 是一个可区分的联合,它是一个对象的值。

试图实现这个,在 js 中工作,但 ts 生气了。 ts playground link

预期:ts 理解循环中的可区分联合,正如它理解的那样没有循环

type TFlavour = ({ 
natural: true,
naturalComponent : string
}) | ({
natural: false,
artificialComponent: string
})

type TIceCream = Record<string, TFlavour>

const IceCreams: TIceCream = {
CokeIceCream: {
natural:false,
artificialComponent: 'Coke'
},
Vanilla: {
natural: true,
naturalComponent: 'Vanilla Extract'
},
Mango: {
natural: true,
naturalComponent: 'Mango Fruit'

}
}


const iceCreamKeys = Object.keys(IceCreams)

iceCreamKeys.forEach( item => {
if(IceCreams[item].natural){
console.log(IceCreams[item].naturalComponent) // ts says "Property doesn't exists.."
}
})


if(IceCreams.Mango.natural){
console.log(IceCreams.Mango.naturalComponent) // Works here
}

最佳答案

问题是编译器不知道怎么做narrowing在像 IceCreams[item] 这样的对象属性上,您正在使用其类型未知的键进行索引 literal type . TypeScript 仅遵循索引的类型,而不是身份item 的类型是string。如果您有 item1item2,两者都是 string 类型,那么检查 IceCreams[item1] 不会让您对 IceCreams[item2] 有任何结论,对吗?由于 TypeScript 无法区分 item1item2itemitem 之间的区别,因此它不能狭窄。这是在 microsoft/TypeScript#10530 中报告的 TypeScript 的已知限制。 .也许有一天它会得到解决。但目前,有一个简单的解决方法:

只需将值复制到一个新变量中,这样有问题的索引只会出现一次:

iceCreamKeys.forEach(item => {
const x = IceCreams[item];
if (x.natural) {
console.log(x.naturalComponent) // okay
}
})

Playground link to code

关于typescript - 即使在使用类型保护检查之后也无法缩小对象属性的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73666799/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com