基于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
(如果未设置),尽管这仍然需要一些强制转换