基于typescript中的构造函数参数重载类属性
在我们的代码库中,我们广泛地使用导航器和构建器模式来抽象层次化对象。它的核心是一个基于typescript中的构造函数参数重载类属性,typescript,typescript-typings,typescript-generics,Typescript,Typescript Typings,Typescript Generics,在我们的代码库中,我们广泛地使用导航器和构建器模式来抽象层次化对象。它的核心是一个Navigator类,我们使用它来遍历不同的类。我目前正在尝试将其迁移到typescript,但我正在努力将其键入以利用typescript的强大功能 我认为我的问题的核心是我不能使用this作为类上泛型的默认值,例如class Something,或者我不能重载类以某种方式有条件地设置类属性的类型。您能否提供一些关于我如何能够在下面键入导航器(和生成器类)的见解 //我想我要做的是 //类导航器,但这是不允许的
Navigator
类,我们使用它来遍历不同的类。我目前正在尝试将其迁移到typescript,但我正在努力将其键入以利用typescript的强大功能
我认为我的问题的核心是我不能使用this
作为类上泛型的默认值,例如class Something
,或者我不能重载类以某种方式有条件地设置类属性的类型。您能否提供一些关于我如何能够在下面键入导航器(和生成器类)的见解
//我想我要做的是
//类导航器,但这是不允许的
类导航器{
//我想更具体地定义这种“back”类型
//也就是说,如果back被传递给构造函数,那么它应该是'BackT'
//如果back未传递给构造函数或未定义,则
//应该是“这”
back:BackT | this;
构造函数(back?:BackT){
this.back=back | | this;
}
}
类生成器1扩展了导航器{
builder1DoSomething(){
//在这里做些工作
归还这个;
}
}
类生成器2扩展了导航器{
withBuilder1(){
返回新的Builder1(此);
//还尝试了以下操作,但我得到了相同的错误:
//返回新的Builder1(此);
}
builder2DoSomething(){
//在这里做些工作
归还这个;
}
}
//这很好
新建Builder1().builder1DoSomething().builder1DoSomething();
新建筑商2()
.withBuilder1()
.builder1DoSomething()
//我在这里得到一个错误,因为我的类型不够具体,无法
//让编辑者知道“返回”已将我带出“构建者1”,并
//返回“Builder2”
.back.builder2DoSomething();
如果没有向类提供类型参数,则可以在back
字段上使用条件类型将其键入this
。我们将使用void
类型作为默认值来表示没有类型参数:
class MyNavigator<BackT = void> {
back: BackT extends void ? this : BackT; // Conditional type
constructor(back?: BackT) {
this.back = (back || this) as any;
}
}
class Builder1<BackT = void> extends MyNavigator<BackT> {
builder1DoSomething() {
return this;
}
}
class Builder2<BackT = void> extends MyNavigator<BackT> {
withBuilder1() {
return new Builder1(this);
}
builder2DoSomething() {
return this;
}
}
new Builder2()
.withBuilder1()
.builder1DoSomething()
// ok now
.back.builder2DoSomething();
类MyNavigator{
back:BackT扩展了void?this:BackT;//条件类型
构造函数(back?:BackT){
this.back=(back | this)如有;
}
}
类生成器1扩展了MyNavigator{
builder1DoSomething(){
归还这个;
}
}
类生成器2扩展了MyNavigator{
withBuilder1(){
返回新的Builder1(此);
}
builder2DoSomething(){
归还这个;
}
}
新建筑商2()
.withBuilder1()
.builder1DoSomething()
//好了
.back.builder2DoSomething();
我认为您最好的选择是为每个类创建一个特殊的变体,它的工作方式与您的选项类似,没有构造函数参数。因此,有一个特殊的SelfNavigator
,SelfBuilder1
等扩展它们相应的类,并且它们本身没有泛型类型
class MyNavigator<BackT> {
back: BackT;
constructor(back: BackT) {
this.back = back;
}
}
class SelfMyNavigator extends MyNavigator<SelfMyNavigator> {}
class Builder1<BackT> extends MyNavigator<BackT> {
builder1DoSomething() {
// Do some work here
return this;
}
}
class SelfBuilder1 extends Builder1<SelfBuilder1> {
constructor() {
super((null as unknown) as SelfBuilder1);
this.back = this;
}
}
class Builder2<BackT> extends MyNavigator<BackT> {
withBuilder1() {
return new Builder1(this);
}
builder2DoSomething() {
// Do some work here
return this;
}
}
class SelfBuilder2 extends Builder2<SelfBuilder2> {
constructor() {
super((null as unknown) as SelfBuilder2);
this.back = this;
}
}
// This is fine
new SelfBuilder1().builder1DoSomething().builder1DoSomething();
new SelfBuilder2()
.withBuilder1()
.builder1DoSomething()
.back.builder2DoSomething();
类MyNavigator{
back:BackT;
构造函数(back:BackT){
this.back=back;
}
}
类SelfMyNavigator扩展MyNavigator{}
类生成器1扩展了MyNavigator{
builder1DoSomething(){
//在这里做些工作
归还这个;
}
}
类SelfBuilder1扩展了Builder1{
构造函数(){
super((null作为未知)作为SelfBuilder1);
this.back=这个;
}
}
类生成器2扩展了MyNavigator{
withBuilder1(){
返回新的Builder1(此);
}
builder2DoSomething(){
//在这里做些工作
归还这个;
}
}
类SelfBuilder2扩展了Builder2{
构造函数(){
super((null作为未知)作为SelfBuilder2);
this.back=这个;
}
}
//这很好
新建SelfBuilder1().Builder1DosMething().Builder1DosMething();
新的SelfBuilder2()
.withBuilder1()
.builder1DoSomething()
.back.builder2DoSomething();
请注意,您不能调用super(this)
,因此将使用丑陋的强制转换。有不同的方法可以避免这种情况,以使代码更好,例如,将所有内容转换为接口和抽象类系统,以便字段back
不在超类中,而是在超接口中。或者将其设置为getter并返回this
(如果未设置),尽管这仍然需要一些强制转换