如何在TypeScript泛型类中从泛型参数提取嵌套类型
解决TypeScript泛型类中提取嵌套类型的问题
问题原因
你遇到的问题是因为BaseEntity的泛型参数T_DATA未在类结构中被使用(或未显式暴露类型信息),导致TypeScript在条件类型推断时,会忽略子类TestEntity继承时传入的具体类型B,转而使用BaseEntity的默认泛型参数A。
解决方案
要正确提取T_DEFAULT_RETURN中嵌套的B类型,需要确保BaseEntity的泛型参数类型信息被保留并可被推断。以下是两种可行的修改方案:
方案一:添加类型层面的属性(无运行时开销)
通过给BaseEntity添加一个仅在类型层面存在的属性,显式暴露泛型参数T_DATA,让AbstractDAL能直接提取该类型:
class A { alpha() { } }; class B extends A { beta() { } }; // 修改BaseEntity,添加类型属性暴露泛型参数 class BaseEntity< T_DATA extends A = A > { // declare关键字确保仅存在于类型系统,不生成运行时代码 declare readonly __dataType: T_DATA; } // 修改AbstractDAL的T_DATA推断逻辑 abstract class AbstractDAL< T_DEFAULT_RETURN extends BaseEntity = BaseEntity, T_DATA = T_DEFAULT_RETURN["__dataType"] > { get result() { return {} as T_DATA } } class TestEntity extends BaseEntity<B> { } class TestDAL extends AbstractDAL<TestEntity> { delta() { this.result.alpha; // 正常访问 this.result.beta; // 现在可以访问beta()了 } }
方案二:在BaseEntity中使用泛型参数(影响运行时)
如果允许在BaseEntity中添加运行时代码,可通过使用泛型参数定义类的属性或方法,让TypeScript保留泛型类型信息:
class A { alpha() { } }; class B extends A { beta() { } }; // 修改BaseEntity,使用泛型参数定义属性 class BaseEntity< T_DATA extends A = A > { constructor(public data: T_DATA) {} } // 原AbstractDAL的条件类型即可正常推断 abstract class AbstractDAL< T_DEFAULT_RETURN extends BaseEntity = BaseEntity, T_DATA = T_DEFAULT_RETURN extends BaseEntity<infer D> ? D : never > { get result() { return {} as T_DATA } } class TestEntity extends BaseEntity<B> { constructor() { super(new B()); } } class TestDAL extends AbstractDAL<TestEntity> { delta() { this.result.alpha; // 正常访问 this.result.beta; // 现在可以访问beta()了 } }
两种方案都能让AbstractDAL正确提取到TestEntity中嵌套的B类型,让this.result同时拥有alpha()和beta()方法。
内容的提问来源于stack exchange,提问作者Nolesh
相关产品推荐
相关产品推荐

