首页 > 解决方案 > 打字稿推断该字段是真实的(不能未定义),没有用户定义的类型保护

问题描述

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. 这是否意味着我需要为我需要检查的每个类型的变体创建一个类型保护函数?没有更简单的方法吗?例如,我希望在证明该left字段不能未定义的 if 检查范围内时,我希望 Typescript 知道这一点。

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

标签: typescriptundefinedtype-inferencetypeguards

解决方案


要回答您的问题:

我假设是因为 Typescript 在这里对这两种类型进行了比较:Itemand ItemRequired,而不是您想要的,即{ left:{ photoSrc:string } }.

Typescript 通常可以在没有类型保护的情况下找出你使用的联合类型的哪一部分,但它还不是很完美。至于哪些会起作用,哪些不会起作用,这是视情况而定的,有很多可能的情况。

很多时候人们都想在没有类型保护的情况下逃脱,这是可以理解的,因为它通常看起来像是额外的、不必要的代码。但它确实是为这种确切情况设计的:

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

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

推荐阅读