将typescript混合应用于泛型基类以获得泛型派生类
在typescript中,我定义了一个带有类型参数将typescript混合应用于泛型基类以获得泛型派生类,typescript,mixins,typescript-generics,Typescript,Mixins,Typescript Generics,在typescript中,我定义了一个带有类型参数T的接口。它适用于超过类型为T的值的某种容器,可以以多种方式实现。接口上的一些方法需要针对每个实现进行专门化。但是其他方法可以给出一个通用实现(通过T),其中结果可以通过调用核心方法来获得。所以我想我可以通过使用mix-in来实现这一点,将一个只实现核心方法的类扩展为一个实现所有方法的类 但是我还没有发现有效的typescript语法,它将混合应用于泛型基类以生成泛型派生类 让我举一个简单的例子。我将接口分为核心部分(Base)和派生部分(der
T
的接口。它适用于超过类型为T
的值的某种容器,可以以多种方式实现。接口上的一些方法需要针对每个实现进行专门化。但是其他方法可以给出一个通用实现(通过T
),其中结果可以通过调用核心方法来获得。所以我想我可以通过使用mix-in来实现这一点,将一个只实现核心方法的类扩展为一个实现所有方法的类
但是我还没有发现有效的typescript语法,它将混合应用于泛型基类以生成泛型派生类
让我举一个简单的例子。我将接口分为核心部分(Base
)和派生部分(derived
)
接口基础{
foo(x:数字):T[];
}
接口派生扩展基{
doubleFoo(x:number):T[];
}
我可以在基本接口上实现一个类,如下所示:
classbaseimpl实现了Base{
构造函数(公共t:t){}
foo(x:数字){
返回新数组(x).fill(this.t);
}
}
现在我想编写一个混合函数,给定的BaseImpl
将返回一个实现派生的
的类。基本实现类和派生实现类都应将T
作为类型参数
我最初尝试了以下方法:
type构造函数=new(…args:any[])=>I;
const MixInDoubleFoo=(基类:C)=>{
返回类扩展派生的基类实现{
doubleFoo(x:数字){
返回此.foo(x*2);
}
}
}
const DerivedImpl=MixInDoubleFoo(BaseImpl);
这样编译不会出错。但结果类似乎丢失了一些类型信息。当我尝试下面的方法时,我犯了一个错误
类MyDerivedFromMixin扩展了DerivedImpl{
tripleFoo(x:number):T[]{
//错误:类型“unknown[]”不可分配给类型“T[]”。
//错误:“未知”类型不可分配给“T”类型。
//错误:“T”可以用与“unknown”无关的任意类型实例化。
返回此.foo(3*x);
}
}
相比之下,如果我尝试以完全相同的方式扩展基本实现类,它编译时不会出错
类MyDerivedFromBaseImpl扩展了BaseImpl{
tripleFoo(x:number):T[]{
返回此.foo(3*x);
}
}
在我看来,typescript类型推断未能将T
视为mix-in返回的函数的类型参数,而是将其替换为unknown
我仔细阅读了这个问题:。这个问题的情况不同——提问者试图将一个类型参数添加到mix-in函数中,而我试图从基类中提升一个类型参数
尽管如此,它还是告诉我,当提供了一些(但不是全部)模板参数时,typescript不会推断类型。我尝试了那里建议的两种解决方案(使用mixin函数,提供额外的伪参数以简化类型推断)。但是,尽管我尝试了许多不同的语法,但没有一种是编译器可以接受的
我希望最终得到的是一个混合,它允许我编写DerivedImpl=MixIn(BaseImpl)
,这样我就可以:
- 创建类的实例:
const instance=new-deriveImpl(…)
- 将其作为参数化的类扩展到
:T
类扩展扩展了deriveImpl{…}
T
上将“派生”方法转换为模板函数,该模板函数以基类为实例。这显然会奏效,只是看起来有点难看
包含上述所有代码的类型脚本: 我使用的是typescript 3.9