如何在抽象类实例间维护Type Safety类型安全
泛型Proxy抽象类的类型安全问题
我需要确保以下使用Proxy的泛型抽象类的类型安全,现有代码拆分如下:
【types.ts】
type FamilyAClient_t = { id: 'A' }; type FamilyBClient_t = { id: 'B' }; interface ClientTable { FamilyA: FamilyAClient_t; FamilyB: FamilyBClient_t; } type Families = keyof ClientTable; type Client<F extends Families> = ClientTable[F];
【controllerAbstract.ts】
abstract class controllerAbstract<F extends Families> { controllerFamily: F; constructor(controllerFamily: F) { this.controllerFamily = controllerFamily; return new Proxy(this, authHandler<F, typeof this>()); } abstract build_client(): Client<F>; authorize(consume_client: (client: Client<F>) => typeof this[keyof typeof this]) { consume_client(this.build_client()); } }
【proxy.ts】
function authHandler< F extends Families, T extends controllerAbstract<F> >(): any { return { get: function (target: T, prop: keyof T): any { return (...args: any[]) => { target.authorize((controllerClient: Client<F>) => { return target[prop](controllerClient, args); }); }; }, }; }
【concrete.ts】
const controllerFamilyName = 'FamilyA'; type ControllerFamliy = typeof controllerFamilyName; class FamilyAController extends controllerAbstract<ControllerFamliy> { constructor() { super(controllerFamilyName); } build_client(): Client<ControllerFamliy> { // build a client of type "FamilyA" const client = { id: 'A' } as Client<ControllerFamliy>; return client; } // proxy "authorize" provides client object useClient(client: any, args: any[]) { // i want client to implicitly be of type "FamilyAClient_t" / Client<"FamilyA"> // currently just using "any" as placeholder } }
注:文中的“concrete类”指concrete.ts中继承抽象类的类,FamilyAController是示例。
目标
让concrete.ts中FamilyAController的useClient方法的client参数根据controllerFamilyName自动推导正确类型:当controllerFamilyName为'FamilyA'时,client自动为Client<"FamilyA">类型,能自动补全client.id为"A";为'FamilyB'时则对应"B"。
当前遇到的问题
- Proxy中
target[prop](...)报错“此表达式不可调用”,因为target[prop]类型为unknown,需限制为可调用属性子集; - 抽象类
authorize方法中consume_client的返回类型定义报错,希望它能自动适配concrete类中任意方法的返回类型,穿透Proxy层保持类型一致。
我曾尝试定义仅包含符合target[props](controllerClient)签名的抽象方法的抽象类,用其keyof修复第一个问题,但仍未达成最终目标。
本质需求
在concrete.ts中编写useClient(client)时,client能自动推导为Client<ControllerFamily>类型,无需为每个concrete类的每个方法手动声明该类型。请问这是否可行?
内容的提问来源于stack exchange,提问作者Chris24t
相关产品推荐
相关产品推荐

