我有以下TypeScript接口,用作ORM库的数据库实体:
export interface Entity {
id?: number;
someColumn: string;
someOtherValue: number;
otherColumn: string;
}
请注意可选的id
属性,它是实体的主键或未定义。
如果未定义,则表示该实体在基础数据库中不存在。
但是,许多函数仅接受具有有效ID的Entity
对象。
因此,我想介绍一个看起来像这样的新界面(不带“?”):
export interface ValidEntity {
id: number;
someColumn: string;
someOtherValue: number;
otherColumn: string;
}
现在我的问题是我不想从原始Entity
界面复制所有属性。
如何通过约束来强制扩展Entity
的{{1}}接口?
另一个问题是同一方向相反的事情。
假设我们已经有了id
接口,并且想要创建一个ValidEntity
接口来放宽Entity
属性以允许未定义。如何在不复制属性的情况下完成这种放松?
答案 0 :(得分:1)
尽管可能还有其他方式产生更漂亮的错误消息, 快速的十字路口类型可以解决问题。
export interface Entity {
id?: number;
someColumn: string;
someOtherValue: number;
otherColumn: string;
}
type ValidEntity = Entity & { id: number };
// Alternate solution:
// type RequiredBy<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>
// type ValidEntity = RequiredBy<Entity, "id">
function f(e: ValidEntity) { }
let obj = {
someColumn: "1",
someOtherValue: 2,
otherColumn: "3"
}
f(obj);
// Property 'id' is missing in type '{ someColumn: string; someOtherValue:
// number; otherColumn: string; }' but required in type '{ id: number; } '.
相反的方向比较棘手。基于this answer,您可以按以下方式使用实用程序类型:
type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>
interface ValidEntity {
id: number;
someColumn: string;
someOtherValue: number;
otherColumn: string;
}
type Entity = PartialBy<ValidEntity, 'id'>