【问题标题】:In typescript, how to convert from union of base interfaces to union of extended interfaces在打字稿中,如何从基本接口的联合转换为扩展接口的联合
【发布时间】:2018-02-08 09:58:06
【问题描述】:

我对 typescript 还很陌生,并且一直在努力思考如何正确使用联合类型。我正在开发一个应用程序,该应用程序将从一个 api 接收一组基本结构,然后用来自其他 api/state 的数据来扩充它们。基本接口集和增强接口都可以是强类型的,所以我想利用它。

我想要完成的事情:

  • 强类型基类型作为基接口集的联合
  • 强类型“装饰”类型作为装饰接口集的联合
  • 它们之间的转换方法

错误发生在转换步骤,因为 typescript 似乎不知道用于装饰的函数遵循接口中定义的规则。我在下面整理了一个最小的示例案例:

type PetKind = 'dog' | 'cat'

interface BasePetInterface {
  kind: PetKind
  name: string
}

interface BaseDog extends BasePetInterface {
  kind: 'dog'
}

interface BaseCat extends BasePetInterface {
  kind: 'cat'
}

type BasePet = BaseDog | BaseCat

function getFluffy(p: BasePet): boolean {
  if (p.kind === 'dog') return true
  if (p.kind === 'cat') return false
}

interface FluffyDog extends BaseDog {
  fluffy: true
}

interface NotFluffyCat extends BaseCat {
  fluffy: false
}

type Pet = FluffyDog | NotFluffyCat

function getPet(p: BasePet): Pet {
  return {
    ...p,
    fluffy: getFluffy(p)
  }
    /* error here ->
       severity: 'Error'
       message: 'Type '{ fluffy: boolean; kind: "dog"; name: string; } 
       | { fluffy: boolean; kind: "cat"; name: string; }' is not 
       assignable to type 'Pet'.
       Type '{ fluffy: boolean; kind: "dog"; name: string; }' is not 
       assignable to type 'Pet'.
       Type '{ fluffy: boolean; kind: "dog"; name: string; }' is not 
       assignable to type 'NotFluffyCat'.
       Types of property 'fluffy' are incompatible.
       Type 'boolean' is not assignable to type 'false'.'
}

上面的“蓬松”是人为的——在实际的应用程序中,这些变量可能取决于其他状态。它们可能是为某些完整类型预先确定的,而在其他类型中可能是有条件的。

有没有办法解决这个问题?或者是否有更好的模式来处理相关基础接口和装饰接口的集合?

【问题讨论】:

    标签: typescript discriminated-union


    【解决方案1】:

    类型 'boolean' 不能分配给类型 'false'。'

    这只是打字稿,发现并非BasePet + boolean 的所有组合都与您的(受限)Pet 匹配。

    如果所有组合都有效Pets,您将不会收到错误消息。

    总结

    你正在做的是有效的:

    type True = true;
    type False = false; 
    type Bool = true | false; 
    
    declare let x: Bool;
    declare let y: False;
    y = x; // Error: same error as you are getting 
    

    【讨论】:

    • 好的,这是有道理的——因为 typescript 只知道 getFluffy 返回一个布尔值,它不知道它根据传入的类型有条件地返回一个布尔值。有可能这样做吗?或者这种使用受约束联合类型的方法不是通常所做的事情?
    猜你喜欢
    • 2017-09-16
    • 1970-01-01
    • 2022-01-04
    • 2019-05-04
    • 2018-01-18
    • 1970-01-01
    • 1970-01-01
    • 2020-10-16
    相关资源
    最近更新 更多