type Item = {
left?: { photoSrc: string };
};
type ItemRequired = {
left: { photoSrc: string };
};
const item: Item = {} as any;
if (item.left) {
const itemRequired: ItemRequired = item; // fails. Typescript still says left may be undefined
// I'd like Typescript to know that field left is truthy
}
我知道用户自定义类型守卫。例如
function isFish(pet: Fish | Bird): pet is Fish {
return (pet as Fish).swim !== undefined;
}
我的问题。
left
不能未定义?left
字段不能未定义,我希望Typescript能知道。这似乎是一个很常见的情况,但我找不到答案,如果有的话请原谅。
回答你的问题。
我猜测是因为Typescript在这里对这两种类型进行了比较, Item
和 ItemRequired
而不是你想要的,那就是 { left:{ photoSrc:string } }
.
Typescript通常可以计算出你使用的联合类型的哪一部分。橆 型守卫,但还不是很完美。哪些能用,哪些不能用,这要根据情况而定,可能的情况有很多。
很多时候,人们想摆脱类型守卫,这也是可以理解的,因为它经常看起来像额外的、不必要的代码。但它确实是为这种确切的情况而设计的。
const itemIsItemRequired = (item: Item): item is ItemRequired =>
item.left !== undefined;
if (itemIsItemRequired(item)) {
const itemRequired: ItemRequired = item; // this works
}
目前,Typescript并不能从Typescript中推断出类型。条件性陈述流.
const item: Item = {} as any;
if (item.left) {
const itemRequired: ItemRequired = item;
}
因此,上述代码块实际上并没有将项目类型从 Item
到 ItemRequired
. 因此,对编译器来说,你试图分配两个不兼容的类型--一个是强制的,另一个是可选的。
正如你所提到的,你可以写一个类型保护,或者简单地,你可以做以下的事情。
const itemRequired: ItemRequired = item as ItemRequired;
然而,我们总是推荐编写类型保护。