在typescript中,如何从基接口的并集转换为扩展接口的并集

时间:2018-02-08 09:58:06

标签: typescript discriminated-union

我对打字稿很新,并且我试图围绕如何正确使用联合类型。我正在开发一个应用程序,它将从一个api接收一组基础结构,然后用来自其他api / state的数据来扩充它们。基本接口集和扩充接口都可以强类型化,因此我想利用它。

我想要完成的事情:

  • 强类型基类型作为基本接口集的并集
  • 强烈打字'装饰'键入作为装饰接口集的联合
  • 在它们之间进行转换的方法

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

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'.'
}

以上'蓬松'是设计的 - 在实际的应用程序中,这些变量可能取决于其他州。它们可能是针对某些完整类型预先确定的,而其他类型则是有条件的。

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

1 个答案:

答案 0 :(得分:2)

  

输入'布尔'不能分配给' false'。'

这只是打字稿,并不是BasePet + boolean的所有组合都与你的(约束的)Pet相匹配。

如果所有组合都有效Pet,则您不会收到错误。

摘要

你正在做的是:

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