【问题标题】:How do I omit result in missing props?如何省略导致缺少道具的结果?
【发布时间】:2021-06-15 19:27:37
【问题描述】:

给定一个基本类型定义

interface Base {
  base: boolean
}

interface AFromBase extends Base {
  propA: number
}

interface BFromBase extends Base {
  propB: number[]
}

type Final = AFromBase | BFromBase

这将导致错误:

类型'{自定义:假; propA:数字; }' 不可分配给类型 '风俗'。对象字面量只能指定已知属性,并且 “自定义”类型中不存在“propA”。ts(2322)

type Custom = Omit<Final, 'base'> & {
  custom: boolean,
}

const instance: Custom = {
  custom: false,
  propA: 123,
  ~~~~~~~~~~
}

但是这行得通

type Custom = (Omit<AFromBase, 'base'> | Omit<BFromBase, 'base'>) & {
  custom: boolean,
}

const instance: Custom = {
  custom: false,
  propA: 123,
}

谁能解释一下为什么会这样?

【问题讨论】:

    标签: typescript


    【解决方案1】:

    联合类型的行为类似于 XOR。所以,如果你想看Final的key

    type Final = AFromBase | BFromBase
    
    type keysOfFinal = keyof Final;
    // returns type keysOfFinal = "base"
    

    让我们添加一个不在Base 中的公共属性

    interface Base {
      base: boolean
    }
    
    interface AFromBase extends Base {
      common: number;
      propA: number
    }
    
    interface BFromBase extends Base {
      common: number;
      propB: number[]
    }
    
    type Final = AFromBase | BFromBase
    
    type keysOfFinal = keyof Final;
    // returns type keysOfFinal = "common" | "base"
    

    因此,OmitFinal 类型的行为与您对表示类型 AFromBase 或类型 BFromBase 的类型的预期不同,这是常识所说的。因此,您会看到您提到的错误。这就是为什么你必须单独 Omit 然后在 Union 中使用它。

    TS Playground 链接:https://tsplay.dev/WYJOzw

    这里是一个使用公共字段联合的例子:https://www.typescriptlang.org/docs/handbook/unions-and-intersections.html#unions-with-common-fields

    我在最新的文档中找不到相同的示例,但这个示例显示了两难境地。我正在粘贴下面的代码以供后代使用:

    interface Bird {
      fly(): void;
      layEggs(): void;
    }
    
    interface Fish {
      swim(): void;
      layEggs(): void;
    }
    
    declare function getSmallPet(): Fish | Bird;
    
    let pet = getSmallPet();
    pet.layEggs();
    
    // Only available in one of the two possible types
    pet.swim();
    Property 'swim' does not exist on type 'Bird | Fish'.
      Property 'swim' does not exist on type 'Bird'.
    

    联合类型在这里可能有点棘手,但需要一点直觉才能习惯。如果一个值的类型为 A | B,我们只知道它有 A 和 B 都有的成员。在此示例中,Bird 有一个名为 fly 的成员。我们不能确定变量类型为 Bird |鱼有飞法。如果变量在运行时确实是 Fish,则调用 pet.fly() 将失败。

    【讨论】:

      猜你喜欢
      • 2019-09-19
      • 2019-09-11
      • 1970-01-01
      • 1970-01-01
      • 2020-06-21
      • 2021-09-04
      • 1970-01-01
      • 1970-01-01
      • 2019-08-27
      相关资源
      最近更新 更多