【发布时间】:2021-07-05 16:28:41
【问题描述】:
给定接口Foo 和Bar,我如何静态地断言这两种类型具有相同的键?
背景:我有一个接口,它既需要用作数据库 DTO,又需要用作“模型”类型。对于数据库 DTO,原语将是常规的 JavaScript 原语。对于“模型”类型,原语将是标称类型(例如 AccountId 而不是 string 等)。目前,我通过定义 2 个接口来实现这一点:一个用于 DTO,一个用于模型。但是,我想要一些方法来确保这些接口不会漂移:
interface Dto {
orderId: string;
invoiceNo: number;
}
interface Model {
orderId: OrderId;
invoiceNo: InvoiceNumber;
}
assertKeysEqual<Dto, Model>() // Compiles OK
interface Dto {
orderId: string;
invoiceNo: number;
x: any;
}
interface Model {
orderId: OrderId;
invoiceNo: InvoiceNumber;
}
assertKeysEqual<Dto, Model>() // Compile ERROR ('Model' does not contain 'x')
interface Dto {
orderId: string;
invoiceNo: number;
}
interface Model {
orderId: OrderId;
invoiceNo: InvoiceNumber;
x: any;
}
assertKeysEqual<Dto, Model>() // Compile ERROR ('Dto' does not contain 'x')
名义类型使用以下方法定义。 但是,更一般地说:键类型的形状可能在类型之间完全不同。例如,在一种类型中,您可能有 order: OrderId,它可以在其“扩展”对应类型中替换为 order: OrderEntity。
export interface OrderId extends String {
_OrderId: string;
}
export function OrderId(value: string): OrderId {
return value as any;
}
知道如何实现assertKeysEqual 之类的东西吗?
【问题讨论】:
-
如何定义 OrderId 和 InvoiceNumber 类型?因为如果我理解你的问题,只需定义 type OrderId = string;类型 InvoiceNumber = 号码;并创建一个可用于 Dto 和 Model 对象的单一接口
-
OrderId和InvoiceNumber是标称类型:我已经更新了描述。
标签: typescript typescript-generics