为什么不能只将具有属性的接口和具有索引签名的接口的交集类型分配给仅具有该属性的对象?

时间:2019-10-29 22:51:06

标签: typescript

为什么我不能仅在属性lastById下定义pairsByIntOrderId

TransactionsByIdState类型是否不具有属性pairsByIntOrderId,并且可以有选择地具有映射到Transaction的字符串类型的其他属性?

interface Transaction {
  amount: number,
  id: string
}

interface PairTransactionsById {
  [id: string]: {
    amount1: number,
    amount2: number,
  }
}
export type TransactionsByIdState = {
  [id: string]: Transaction;
} & { pairsByIntOrderId: PairTransactionsById };

const lastById: TransactionsByIdState = { pairsByIntOrderId: {} };

2 个答案:

答案 0 :(得分:1)

  

为什么我不能仅在属性对PairsByIntOrderId下定义lastById?

因为索引签名会强制执行所有 属性match its return type

使用类型TransactionsByIdState基本上是说所有字符串属性都必须具有Transaction类型。此条件适用于财产 pairsByIntOrderId也是如此,它是通过交叉点添加的。

pairsByIntOrderId也被声明为PairTransactionsById类型。由于PairTransactionsById无法分配给Transaction,因此您已经在此处创建了一个“永不满足”类型。唯一防止编译器发出错误的是,交集永远不会产生错误(比较herehere)。

话虽如此,具体的解决方案取决于您的用例和类型要求。您可以签出并订阅此feature request以获取具有索引签名+属性的混合类型。如果TransactionPairTransactionsById不兼容(在这里似乎是这种情况),则应将它们独立存储。同样,separating index signature from explicit properties通常是很好的打字经验法则。

答案 1 :(得分:0)

您不能为pairsByIntOrderId分配空对象,因为它的类型需要两个字段-amountid。 TypeScript需要它们,因为它们不是可选的。有两种解决方法:

您可以将两个字段都设为可选;

interface Transaction {
   amount?: number;
   id?: string;
}

或使用Partial类型,它会在每个字段可选的情况下构造一个新类型;

[id: string]: Partial<Transaction>;