如何在 TypeScript 的派生类中进行构造函数重载?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26155054/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I do constructor overloading in a derived class in TypeScript?
提问by Lee H
Assuming I have a 'base' class such as this:
假设我有一个像这样的“基”类:
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
}
}
}
I want to be able to extend this base class while still supporting constructor overloading. For example:
我希望能够扩展这个基类,同时仍然支持构造函数重载。例如:
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
}
}
}
The problem is that Typescript demands that the 'super' keyword appear first (literally) in the constructor implementation. The specific build error message is:
问题在于 Typescript 要求在构造函数实现中首先(字面意思)出现 'super' 关键字。具体的构建错误信息是:
"A 'super' call must be the first statement in the constructor when a class contains initialized properties or has parameter properties."
“当类包含初始化属性或具有参数属性时,'super' 调用必须是构造函数中的第一条语句。”
However, I need to determine which parameters I will pass into the 'super' (i.e. use a different constructor overload) based upon what was supplied to the extended (derived) class. You should assume here that the derived class' constructor overloads may be very different from the super's.
但是,我需要根据提供给扩展(派生)类的内容来确定将哪些参数传递给“超级”(即使用不同的构造函数重载)。您应该在这里假设派生类的构造函数重载可能与超级类的构造函数重载非常不同。
Is there a workaround for what I'm trying to achieve?
我想要实现的目标有解决方法吗?
采纳答案by Ryan Cavanaugh
This restriction only applies if you have initializedmember properties in the derived class, so the first workaround is to simply only declarethose properties and then initialize them in the derived class constructor.
此限制仅适用于在派生类中初始化成员属性的情况,因此第一个解决方法是仅声明这些属性,然后在派生类构造函数中初始化它们。
In other words, you can change:
换句话说,您可以更改:
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);
}
}
}
to this:
对此:
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);
}
}
}
Note that the initialization order here is roughly the same as in other OOP languages and you need to be careful about not calling virtual methods from constructors, etc.
请注意,这里的初始化顺序与其他 OOP 语言中的初始化顺序大致相同,您需要注意不要从构造函数等调用虚方法。
If that's too distasteful, note that the restriction is simply that the first statementbe a super call. You can often refactor the super call:
如果这太令人反感,请注意限制只是第一条语句是超级调用。您通常可以重构 super 调用:
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);
}
}
Not the prettiest, but it's at least semantically equivalent. This does assume your base class constructor is checking for undefined
(instead of arguments.length
) to determine which overload was invoked.
不是最漂亮的,但至少在语义上是等效的。这确实假设您的基类构造函数正在检查undefined
(而不是arguments.length
)以确定调用了哪个重载。