如何实现可覆写类型属性的通用服务类以支持继承复用?
解决方案:创建可继承的泛型实体服务类
核心思路
将EntityService改造为泛型类,通过泛型参数绑定实体类(如Class_A)和对应的接口类型(如Entity_A),同时通过构造函数注入实体类的构造函数,实现父类逻辑复用,子类仅需指定类型即可自动获得匹配的方法签名。
修改后的完整代码
declare class Observable<T> { x: T } declare class Actor { doStuff<T>(anything: T): T[]; getData<I>(): I; getObservable<U, I>(data: I): Observable<U[]>; } interface Entity { param_1: number, param_2: number, } class EntityObj { id: string; param_1: number; param_2: number; constructor(id: string, param_1: number, param_2: number) { this.id = id; this.param_1 = param_1; this.param_2 = param_2; } } // 定义构造函数类型约束,确保实体类具备fromInterface静态方法 type EntityObjConstructor<EntityType extends Entity, EntityObjType extends EntityObj> = { new(id: string, param_1: number, param_2: number, ...args: any[]): EntityObjType; fromInterface(entity: EntityType, id: string): EntityObjType; }; export class EntityService<EntityObjType extends EntityObj, EntityType extends Entity> { private readonly entityCtor: EntityObjConstructor<EntityType, EntityObjType>; constructor( private readonly actor: Actor, entityCtor: EntityObjConstructor<EntityType, EntityObjType> ) { this.entityCtor = entityCtor; } getEntityObjs(): Observable<EntityObjType[]> | null { const data = this.actor.getData<EntityType>(); return this.actor.getObservable<EntityObjType, EntityType>(data); } getObjFromInterface(): EntityObjType { const entity = this.actor.getData<EntityType>(); return this.entityCtor.fromInterface(entity, "foo"); } update(entity: EntityObjType): void { // 类型断言:EntityObjType包含EntityType的所有属性,转换安全 const entityDoc = this.actor.doStuff<EntityType>(entity as unknown as EntityType); } } // ------------------------------ // 示例子类:Service_A 与 Class_A // ------------------------------ interface Entity_A extends Entity { param_3: string; } class Class_A extends EntityObj { param_3: string; constructor(id: string, param_1: number, param_2: number, param_3: string) { super(id, param_1, param_2); this.param_3 = param_3; } static fromInterface(entity: Entity_A, id: string): Class_A { return new this(id, entity.param_1, entity.param_2, entity.param_3); } } export class Service_A extends EntityService<Class_A, Entity_A> { constructor(actor: Actor) { super(actor, Class_A); } } // ------------------------------ // 示例子类:Service_B 与 Class_B // ------------------------------ interface Entity_B extends Entity { param_4: boolean; } class Class_B extends EntityObj { param_4: boolean; constructor(id: string, param_1: number, param_2: number, param_4: boolean) { super(id, param_1, param_2); this.param_4 = param_4; } static fromInterface(entity: Entity_B, id: string): Class_B { return new this(id, entity.param_1, entity.param_2, entity.param_4); } } export class Service_B extends EntityService<Class_B, Entity_B> { constructor(actor: Actor) { super(actor, Class_B); } }
关键细节说明
泛型约束:
EntityObjType extends EntityObj:确保实体类必须继承基础EntityObjEntityType extends Entity:确保接口必须继承基础Entity
构造函数注入:
父类通过构造函数接收实体类的构造函数引用,这样可以调用子类实体的fromInterface静态方法,避免硬编码基础类。自动类型匹配:
子类继承时指定泛型类型后,所有方法的参数和返回值会自动绑定到对应类型:Service_A.update()自动接收Class_A类型参数Service_A.getEntityObjs()自动返回Observable<Class_A[]>类型
类型转换安全:
update方法中的类型断言entity as unknown as EntityType是安全的,因为EntityObjType继承自EntityObj(包含Entity的所有属性),且EntityType是对应实体类的接口,属性完全匹配。
内容的提问来源于stack exchange,提问作者Faeralis
相关产品推荐
相关产品推荐

