Typescript推断该字段是真实的(不能是未定义的),没有用户定义的类型保护。

问题描述 投票:0回答:1
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;
}

我的问题。

  1. 为什么Typescript无法推断出 left 不能未定义?
  2. 这是否意味着我需要为我需要检查的类型的每一个变化创建一个类型保护函数?难道没有更简单的方法吗?例如,我希望在if检查的范围内证明 left 字段不能未定义,我希望Typescript能知道。

这似乎是一个很常见的情况,但我找不到答案,如果有的话请原谅。

typescript undefined type-inference typeguards
1个回答
1
投票

回答你的问题。

我猜测是因为Typescript在这里对这两种类型进行了比较, ItemItemRequired而不是你想要的,那就是 { left:{ photoSrc:string } }.

Typescript通常可以计算出你使用的联合类型的哪一部分。 型守卫,但还不是很完美。哪些能用,哪些不能用,这要根据情况而定,可能的情况有很多。

很多时候,人们想摆脱类型守卫,这也是可以理解的,因为它经常看起来像额外的、不必要的代码。但它确实是为这种确切的情况而设计的。

const itemIsItemRequired = (item: Item): item is ItemRequired =>
  item.left !== undefined;

if (itemIsItemRequired(item)) {
    const itemRequired: ItemRequired = item; // this works
}

0
投票

目前,Typescript并不能从Typescript中推断出类型。条件性陈述流.

const item: Item = {} as any;
if (item.left) {
    const itemRequired: ItemRequired = item; 
}

因此,上述代码块实际上并没有将项目类型从 ItemItemRequired. 因此,对编译器来说,你试图分配两个不兼容的类型--一个是强制的,另一个是可选的。

正如你所提到的,你可以写一个类型保护,或者简单地,你可以做以下的事情。

const itemRequired: ItemRequired = item as ItemRequired;

然而,我们总是推荐编写类型保护。

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