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})