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

能否创建可跨方法复用的动态类型?ExperimentService类型问题咨询

实现可复用的动态类型,让getItem识别__items的动态类型

可以实现这个需求,问题出在原代码中getItem的泛型约束typeof this.__items绑定的是类定义时__items的原始类型(string),而非实例被断言后的动态类型。以下是两种可行的修改方案:

方案一:通过this参数的索引类型动态绑定

直接修改getItem的泛型约束,让它依赖于当前实例的__items类型,而非类定义时的静态类型:

class ExperimentService {
  //...
  public __items: string;

  public uploadExperiments<Payload extends Dictionary<ExperimentItemType[]>>(payload: Payload): asserts this is this & Record<"__items", keyof Payload> {
    // ...
  }

  // 改用 this["__items"] 作为泛型约束,动态关联当前实例的__items类型
  public getItem<Name extends this["__items"]>(name: Name) {
    // ...
  }
}

const expirementService = new ExperimentService();
expirementService.uploadExperiments({ mock: [...] });
expirementService.getItem("mock"); // 类型校验通过,只能传入"mock"
expirementService.getItem("other"); // 类型报错

这种方式利用了TypeScript中this类型的动态特性,当实例通过asserts this is ...改变类型后,this["__items"]会自动更新为最新的keyof Payload类型,从而让getItem的泛型参数约束同步变化。

方案二:将类设计为泛型类

把__items的类型作为类的泛型参数,从根源上让类的方法类型跟随泛型参数动态调整:

// 泛型参数T默认值为string,对应初始状态的__items类型
class ExperimentService<T extends string = string> {
  public __items: T;

  // 断言this变为泛型参数为keyof Payload的实例类型
  public uploadExperiments<Payload extends Dictionary<ExperimentItemType[]>>(payload: Payload): asserts this is ExperimentService<keyof Payload> {
    // ...
  }

  // 泛型约束直接绑定类的泛型参数T
  public getItem<Name extends T>(name: Name) {
    // ...
  }
}

const expirementService = new ExperimentService();
expirementService.uploadExperiments({ mock: [...] });
expirementService.getItem("mock"); // 类型校验通过
expirementService.getItem("other"); // 类型报错

这种方案通过泛型参数将__items的类型与整个类的类型绑定,调用uploadExperiments后,实例的泛型参数被断言为keyof Payload,getItem的泛型约束自然会同步更新为该类型。

内容的提问来源于stack exchange,提问作者HookeD74

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 11:20:37