You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在抽象类实例间维护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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 18:40:26