如何实现泛型类型将Entity及其子对象的id和version设为可选?
问题描述
我们所有数据库表都包含标识符(id)和version属性,所有具体实体都继承自以下Entity接口:
interface Entity { id: number; version: number; }
以下是一个多层级实体示例:
interface Address extends Entity { street: string; hno: string; zip: string; city: string; country: string; } interface Department extends Entity { name: string; } interface User extends Entity { name: string; birthday: string; address: Address; department: Department; }
现在需要实现一个泛型类型,将所有层级(包括子对象)中的id和version字段改为可选类型。比如将User从:
type OriginalUser = { id: number; version: number; name: string; birthday: string; address: { id: number; version: number; street: string; hno: string; zip: string; city: string; country: string; }; department: { id: number; version: number; name: string; }; }
转换为:
type TransformedUser = { id?: number; version?: number; name: string; birthday: string; address: { id?: number; version?: number; street: string; hno: string; zip: string; city: string; country: string; }; department: { id?: number; version?: number; name: string; }; }
目前已有一个初步实现,但仅移除了id和version字段,缺少将其重新定义为可选类型的部分:
export type NewEntity<T extends Entity> = { // remove id and version fields [K in keyof Omit<T, 'id' | 'version'>]: T[K] extends Entity ? NewEntity<T[K]> : T[K]; };
需要完善该泛型类型以满足需求。
解决方案
通过交叉类型将移除的id/version字段重新定义为可选,同时递归处理所有嵌套的Entity类型:
export type PartialEntityIds<T extends Entity> = // 将id和version设为可选 Partial<Pick<T, 'id' | 'version'>> & // 处理其他字段,递归嵌套的Entity { [K in keyof Omit<T, 'id' | 'version'>]: T[K] extends Entity ? PartialEntityIds<T[K]> : T[K] };
代码说明
Partial<Pick<T, 'id' | 'version'>>:从原类型中提取id和version字段,通过Partial将它们转为可选类型。- 交叉类型
&:把可选的id/version与处理后的其他字段合并,完整保留原类型的所有属性结构。 - 递归处理嵌套实体:对于其他字段,若该字段本身是
Entity的子类,就递归应用PartialEntityIds,确保所有层级的id/version都被转为可选。
验证示例
用User类型测试:
type TransformedUser = PartialEntityIds<User>; // 最终结构完全符合需求: // { // id?: number; // version?: number; // name: string; // birthday: string; // address: PartialEntityIds<Address>; // 内部id/version已可选 // department: PartialEntityIds<Department>; // 内部id/version已可选 // }
内容的提问来源于stack exchange,提问作者user2622344
相关产品推荐
相关产品推荐

