如何正确键入从 Record<> 扩展的接口的交集?

How to properly type the intersection of interfaces extending from Record<>?

它本来应该是直截了当的...我已将我的问题分解为最简单、最少的代码来重现我的问题

首先定义一个类型,具有所有记录的一般形状

type BaseRecord = Record<string, number|string>

然后定义具体的记录接口

interface RecordA extends BaseRecord {}

interface RecordB extends BaseRecord {}

接下来定义最终文档的形状,它由一个RecordA和一个RecordB

的集合组成
interface Collection {
    bees: RecordB[]
}

type WithCollection = RecordA & Collection

最后,撰写文档

declare const a: RecordA
declare const c: Collection
const d: WithCollection = {...a, ...c}

此处,上面最后一行在分配 d

时失败并显示 Type ... is not assignable to type ...

如果我从 RecordA 中删除 extends BaseRecord,错误就会消失(以及从 BaseRecord 扩展的好处)。

实际代码实际上更复杂,因为 BaseRecord 具有高级值类型,而 RecordA 和 RecordB 具有许多属性。

这是一个playground reproducing the issue

将赋值语句显式转换为您的交集类型:

type BaseRecord = Record<string, number | string>

interface RecordA extends BaseRecord { }
interface RecordB extends BaseRecord { }

interface Collection {
    bees: RecordB[]
}

type WithCollection = RecordA & Collection

const a: RecordA = { "foo": 1, "bar": "2", };
const c: Collection = { bees: [{"maya": "hello maya"}] };
const d = { ...a, ...c } as WithCollection // cast object to intersectiontype

这里有一个 运行 playground 例子。