能否创建可跨方法复用的动态类型?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
相关产品推荐
相关产品推荐

