假设我有一个'基础'类,如:
class CcDefinition {
// Some properties here
constructor (json: string);
constructor (someVar: number, someOtherVar: string);
constructor (jsonOrSomeVar: any, someOtherVar?: string) {
if (typeof jsonOrSomeVar=== "string") {
// some JSON wrangling code here
} else {
// assign someVar and someOtherVar to the properties
}
}
}
我希望能够在支持构造函数重载的同时扩展此基类。例如:
class CcDerived extends CcDefinition {
// Some additional properties here
constructor (json: string);
constructor (someVar: boolean, someOtherVar: number, someAdditionalVar: string);
constructor (jsonOrSomeVar: any, someOtherVar?: number, someAdditionalVar?: string) {
if (typeof jsonOrSomeVar=== "string") {
super.constructFromJson(jsonOrSomeVar);
} else {
super.constructFromDef(someOtherVar, someAdditionalVar);
// assign someVar to the additional properties of this derived class
}
}
}
问题是,Typescript要求'super'关键字在构造函数实现中首先出现(字面上)。具体的构建错误消息是:
当一个类包含初始化属性或具有参数属性时,“超'调用必须是构造函数中的第一个语句。”
但是,我需要根据提供给扩展(派生)类的内容确定将传递给'super'的参数(即使用不同的构造函数重载)。你应该假设派生类的构造函数重载可能与super的非常不同。
我正在努力实现的目标是什么?
答案 0 :(得分:7)
此限制仅适用于派生类中初始化成员属性的情况,因此第一种解决方法是仅声明这些属性,然后在派生中初始化它们类构造函数。
换句话说,你可以改变:
class CcDerived extends CcDefinition {
y = 10;
constructor (json: string);
constructor (someVar: boolean, someOtherVar: number, someAdditionalVar: string);
constructor (jsonOrSomeVar: any, someOtherVar?: number, someAdditionalVar?: string) {
if (typeof jsonOrSomeVar=== "string") {
super(jsonOrSomeVar);
} else {
super(someOtherVar, someAdditionalVar);
}
}
}
到此:
class CcDerived extends CcDefinition {
// Some additional properties here
y: number;
constructor (json: string);
constructor (someVar: boolean, someOtherVar: number, someAdditionalVar: string);
constructor (jsonOrSomeVar: any, someOtherVar?: number, someAdditionalVar?: string) {
this.y = 10;
if (typeof jsonOrSomeVar=== "string") {
super(jsonOrSomeVar);
} else {
super(someOtherVar, someAdditionalVar);
}
}
}
请注意,此处的初始化顺序与其他OOP语言大致相同,您需要注意不要从构造函数等调用虚方法。
如果这太令人反感,请注意限制只是第一个语句是超级调用。你经常可以重构超级电话:
class CcDerived extends CcDefinition {
constructor (json: string);
constructor (someVar: boolean, someOtherVar: number, someAdditionalVar: string);
constructor (jsonOrSomeVar: any, someOtherVar?: number, someAdditionalVar?: string) {
super(
typeof jsonOrSomeVar === 'string' ? jsonOrSomeVar : someOtherVar,
typeof jsonOrSomeVar === 'string' ? undefined : someAdditionalVar);
}
}
不是最漂亮的,但它至少在语义上是等同的。这假设您的基类构造函数正在检查undefined
(而不是arguments.length
)以确定调用了哪个重载。