有没有简单的方法可以将所有单个接口扩展为这些接口的并集类型?

时间:2019-10-18 09:04:02

标签: typescript

我有三个不同的界面

target_mean = df_train.groupby(['id1', 'id2'])['target'].mean().to_dict()
df_test['avg'] = df_test.set_index(['id1', 'id2']).index.map(target_mean)

例如,响应就是我从API请求中获得的信息。但是,在获得响应之后,我需要进行另一个API调用以获取第一个属性中未包含的订单的属性,假设该属性的类型为interface SmallOrder { prop1: string } interface MediumOrder { prop2: string } interface LargeOrder { prop3: string } type Order = SmallOrder | MediumOrder | LargeOrder; type Res = Order[] type Country = 'US' | 'International' 。发出该请求时,我会将这个属性添加到我先前保存的每个订单中。问题是,我如何轻松键入这些新订单。

我想要类似下面的内容(由于Order不是接口,因此显然不起作用),但是我想要的类型是

Country

很明显,我可以定义接口interface OrderWithCountry extends Order { country: Country } so that it would become something like type OrderWithCountry = SmallOrderWithCountry | MediumOrderWithCountry | LargeOrderWithCountry 等,然后定义SmallOrderWithCountry,但是如果我有五十种订单类型,该怎么办。 有更简单的方法吗?

编辑: 我以为下面的第一个答案有解决方案,但是下面的示例仍然存在问题。特别是为什么我不能编写检查OrderWithCountry的if语句?我可能在这里需要类型保护,但为什么我什至不能只检查属性?

o.common

1 个答案:

答案 0 :(得分:1)

如果我正确理解了您想要的内容,则应该使用intersection typeofficial handbook)。

type OrderWithCountry = Order & {
  country: Country
}

在类型化上下文中,&是类型交集运算符,将其操作数中的所有属性组合为一个新类型。

对于第二个关于common属性的问题,TS不允许您在没有类型保护的情况下使用它,因为它并非在所有类型上都存在。编写和使用类型保护的一种方法是这样的(您可以修改名称和特定类型的约束以适合您的实际情况):

function isOrderWithCommonProp(o: OrderExt & { common?: string }): o is OrderExt & { common: string } {
  return !!o.common
}

myExtOrders.map(o => {
  if (isOrderWithCommonProp(o)) {
    o.common.trim()
  }
})