Typescript 返回时的类继承";这";在静态和公共方法中

Typescript 返回时的类继承";这";在静态和公共方法中,typescript,class,inheritance,Typescript,Class,Inheritance,我试图更好地理解类继承我有一些技巧可以用来键入静态方法,但我想详细介绍我遇到的一个常见情况,看看是否有其他方法来看待它 这里我有一个Root类我希望每个类都有这些方法,一些是公共方法(main和fork)和一个静态方法main),每个方法都有一个参数props,它是一个普通对象。每个类向该对象添加与该类相关的特定属性 这些类都不需要构造函数,但我确实意识到,使用此类参数继承可能有助于使用ConstructorParameters[0],我对此持开放态度,我尝试过T['props'],但它不起作用

我试图更好地理解类继承我有一些技巧可以用来键入静态方法,但我想详细介绍我遇到的一个常见情况,看看是否有其他方法来看待它

这里我有一个
Root
类我希望每个类都有这些方法,一些是公共方法(
main
fork
)和一个静态方法
main
),每个方法都有一个参数
props
,它是一个普通对象。每个类向该对象添加与该类相关的特定属性

这些类都不需要构造函数,但我确实意识到,使用此类参数继承可能有助于使用
ConstructorParameters[0]
,我对此持开放态度,我尝试过
T['props']
,但它不起作用

对于静态和公共方法,主要问题是返回
this
,而不是
Root
。通过使用
T extends Root
并定义
this:T
,可以为静态方法使用
InstanceType
。我对此也持开放态度,但我还需要为
道具
进行基于分类的特定键入

如果必要的话,我愿意使用泛型类,但如果可以的话,我想避开它

class Root {
  props?: {root?: boolean} = {};
  main(props?: Root['props']) {
    this.props = {...this.props, ...props};
    return this;
  }
  fork(props?: Root['props']) {
    return new Root().main({...this.props, ...props});
  }
  static main(props?: Root['props']) {
    return new this().main(props);
  }
}

class Alpha extends Root {
  props?: Root['props'] & {alpha?: boolean};
}

class Beta extends Alpha {
  props?: Alpha['props'] & {beta?: boolean};
}

class Gamma extends Beta {
  props?: Beta['props'] & {gamma?: boolean};
}

const g = Gamma.main({beta: true}); // fails beta & returns instance of Root :(
console.log(g);


如何正确键入这些方法?因此,
g
被键入为
Gamma
的一个实例,并且
props
参数被键入到
Gamma
beta
alpha

这里有一个使用泛型的解决方案:

键入GetProps any>=构造函数参数[0];
类根{
构造函数(公共属性:{root?:boolean}={}}{};
主(道具?:获取道具){
this.props={…this.props,…props};
归还这个;
}
叉子(道具?:获取道具){
返回新的Root().main({…this.props,…props});
}
静态main(this:T,props?:GetProps):InstanceType{
返回新的this().main(props)作为InstanceType;
}
}
类Alpha扩展了根{
构造函数(公共属性:GetProps&{alpha?:boolean}){
超级(道具);
};
}
贝塔类扩展了阿尔法{
构造函数(公共属性:GetProps&{beta?:boolean}){
超级(道具);
};
}
Gamma类扩展了Beta类{
构造函数(公共属性:GetProps&{gamma?:boolean}){
超级(道具);
};
}
常数a=Gamma.main({beta:true})
常量b=Gamma.main({beta:true}).main({beta:true})
type GetProps<T extends new (...args: any) => any> = ConstructorParameters<T>[0];

class Root<T extends typeof Root> {
  constructor(public props: {root?: boolean} = {}) {};
  main(props?: GetProps<T>) {
    this.props = {...this.props, ...props};
    return this;
  }
  fork(props?: GetProps<T>) {
    return new Root().main({...this.props, ...props});
  }
  static main<T extends typeof Root>(this: T, props?: GetProps<T>): InstanceType<T> {
    return new this().main(props) as InstanceType<T>;
  }
}

class Alpha<T extends typeof Alpha> extends Root<T> {
  constructor(public props: GetProps<typeof Root> & {alpha?: boolean}) {
    super(props);
  };
}

class Beta<T extends typeof Beta> extends Alpha<T> {
    constructor(public props: GetProps<typeof Alpha> & {beta?: boolean}) {
    super(props);
  };
}

class Gamma<T extends typeof Gamma> extends Beta<T> {
    constructor(public props: GetProps<typeof Beta> & {gamma?: boolean}) {
    super(props);
  };
}

const a = Gamma.main({beta: true})
const b = Gamma.main({beta: true}).main({beta: true})