Javascript 有没有办法在TypeScript中实现方法重载?
有没有办法在TypeScript语言中实现方法重载 我想实现这样的目标:Javascript 有没有办法在TypeScript中实现方法重载?,javascript,typescript,operator-overloading,Javascript,Typescript,Operator Overloading,有没有办法在TypeScript语言中实现方法重载 我想实现这样的目标: class TestClass { someMethod(stringParameter: string): void { alert("Variant #1: stringParameter = " + stringParameter); } someMethod(numberParameter: number, stringParameter: string): void {
class TestClass {
someMethod(stringParameter: string): void {
alert("Variant #1: stringParameter = " + stringParameter);
}
someMethod(numberParameter: number, stringParameter: string): void {
alert("Variant #2: numberParameter = " + numberParameter + ", stringParameter = " + stringParameter);
}
}
var testClass = new TestClass();
testClass.someMethod("string for v#1");
testClass.someMethod(12345, "string for v#2");
const config = new SomeMethodConfig('text');
config.numberParameter = 123; // initialize an optional parameter only if you want to do it
this.SomeMethod(config);
下面是一个我不想做的例子(我真的很讨厌JS中的重载攻击):
为清晰起见,请更新。TypeScript中的方法重载是一个有用的功能,因为它允许您使用需要表示的API为现有库创建类型定义 不过,在编写自己的代码时,您可以使用可选或默认参数避免重载的认知开销。这是方法重载的更具可读性的替代方法,还可以保持API的诚实性,因为这样可以避免使用不直观的顺序创建重载 TypeScript重载的一般规律是: 通常,您可以使用可选参数或默认参数,或者使用联合类型,或者使用一点对象定向来实现相同的功能 实际问题 实际问题要求过载:
someMethod(stringParameter: string): void {
someMethod(numberParameter: number, stringParameter: string): void {
现在,即使在使用单独实现支持重载的语言中(注意:TypeScript重载共享一个实现),程序员也建议在排序时提供一致性。这将使签名:
someMethod(stringParameter: string): void {
someMethod(stringParameter: string, numberParameter: number): void {
stringParameter
始终是必需的,因此它是第一个参数。您可以将其作为工作类型脚本重载编写:
someMethod(stringParameter: string): void;
someMethod(stringParameter: string, numberParameter: number): void;
someMethod(stringParameter: string, numberParameter?: number): void {
if (numberParameter != null) {
// The number parameter is present...
}
}
但是根据TypeScript重载的规律,我们可以删除重载签名,并且我们的所有测试仍然会通过
someMethod(stringParameter: string, numberParameter?: number): void {
if (numberParameter != null) {
// The number parameter is present...
}
}
实际的问题,按照实际的顺序
如果决定保持原始顺序,则重载将为:
someMethod(stringParameter: string): void;
someMethod(numberParameter: number, stringParameter: string): void;
someMethod(a: string | number, b?: string | number): void {
let stringParameter: string;
let numberParameter: number;
if (typeof a === 'string') {
stringParameter = a;
} else {
numberParameter = a;
if (typeof b === 'string') {
stringParameter = b;
}
}
}
现在需要进行大量的分支来确定参数的放置位置,但是如果您阅读到目前为止的内容,您确实希望保持这种顺序。。。但是等等,如果我们应用TypeScript重载定律会发生什么呢
someMethod(a: string | number, b?: string | number): void {
let stringParameter: string;
let numberParameter: number;
if (typeof a === 'string') {
stringParameter = a;
} else {
numberParameter = a;
if (typeof b === 'string') {
stringParameter = b;
}
}
}
分支已经足够了
当然,考虑到我们需要做的类型检查的数量。。。也许最好的答案就是有两种方法:
someMethod(stringParameter: string): void {
this.someOtherMethod(0, stringParameter);
}
someOtherMethod(numberParameter: number, stringParameter: string): void {
//...
}
根据规范,TypeScript确实支持方法重载,但它非常笨拙,并且包含许多检查参数类型的手工工作。我认为这主要是因为在普通JavaScript中,最接近方法重载的方法包括检查,TypeScript也尝试不修改实际的方法体,以避免任何不必要的运行时性能开销 如果我理解正确,您必须首先为每个重载编写一个方法声明,然后编写一个方法实现来检查其参数以确定调用了哪个重载。实现的签名必须与所有重载兼容
class TestClass {
someMethod(stringParameter: string): void;
someMethod(numberParameter: number, stringParameter: string): void;
someMethod(stringOrNumberParameter: any, stringParameter?: string): void {
if (stringOrNumberParameter && typeof stringOrNumberParameter == "number")
alert("Variant #2: numberParameter = " + stringOrNumberParameter + ", stringParameter = " + stringParameter);
else
alert("Variant #1: stringParameter = " + stringOrNumberParameter);
}
}
我希望如此。我也想要这个功能,但是TypeScript需要与没有重载方法的非类型化JavaScript进行互操作。i、 如果重载方法是从JavaScript调用的,那么它只能被分派到一个方法实现 关于codeplex有一些相关的讨论。e、 g 我仍然认为TypeScript应该生成所有的if'ing和switching,这样我们就不需要这样做了。为什么不将其用作函数参数 对于本问题中的情况,使用由一些可选属性定义的内联接口只能直接生成如下代码:
class TestClass {
someMethod(arg: { stringParameter: string, numberParameter?: number }): void {
let numberParameterMsg = "Variant #1:";
if (arg.numberParameter) {
numberParameterMsg = `Variant #2: numberParameter = ${arg.numberParameter},`;
}
alert(`${numberParameterMsg} stringParameter = ${arg.stringParameter}`);
}
}
var testClass = new TestClass();
testClass.someMethod({ stringParameter: "string for v#1" });
testClass.someMethod({ numberParameter: 12345, stringParameter: "string for v#2" });
因为TypeScript中提供的重载,正如其他人的评论中所提到的,只是函数不同签名的列表,而不像其他静态语言那样支持相应的实现代码。因此,实现仍然必须只在一个函数体中完成,这使得在Typescript中使用函数重载不像支持真正重载特性的语言那样容易
然而,在typescript中仍然提供了许多新的和方便的东西,这在传统编程语言中是不可用的,我认为匿名接口中的可选属性支持是一种满足传统函数重载舒适区的方法。如果有很多方法重载的变体,另一种方法是创建一个包含所有参数的类。所以,您可以按任意顺序只传递所需的参数
class SomeMethodConfig {
stringParameter: string;
numberParameter: number;
/**
*
*/
constructor(stringParameter: string = '012', numberParameter?: number) { // different ways to make a param optional
this.numberParameter = 456; // you can put a default value here
this.stringParameter = stringParameter; // to pass a value throw the constructor if necessary
}
}
您还可以使用默认值创建构造函数和/或传递一些强制参数。然后就这样使用:
class TestClass {
someMethod(stringParameter: string): void {
alert("Variant #1: stringParameter = " + stringParameter);
}
someMethod(numberParameter: number, stringParameter: string): void {
alert("Variant #2: numberParameter = " + numberParameter + ", stringParameter = " + stringParameter);
}
}
var testClass = new TestClass();
testClass.someMethod("string for v#1");
testClass.someMethod(12345, "string for v#2");
const config = new SomeMethodConfig('text');
config.numberParameter = 123; // initialize an optional parameter only if you want to do it
this.SomeMethod(config);
这通常不称为方法重载。还可以看到问题,第一个参数的类型发生了变化。我承认在我的回答中,您将把可选参数放在最后,因此
number
参数将是第二个参数,并且是可选的。TypeScript不支持“正确的”方法重载-但即使是C世界也正在从重载转向可选参数,因为在许多情况下,它会导致更可读的代码。您的意思是if(typeof numberParameter!=“undefined”)
,对吗这取决于您的用例,尤其是您是否接受零。如果需要,请记住使用==代码>以避免杂耍。@Sebastian这听起来像是一个依赖注入的机会。鉴于TypeScript中的方法重载涉及到具有多个修饰、默认参数和联合类型的单个方法,因此提供了更好的体验。如果方法在更重要的方面有所不同,您可以使用一个抽象,或者实现多个方法。@hakre这么说很奇怪,因为TypeScript已经支持方法重载了。@svick:那么,您称之为方法重载吗?在您的回答中,方法本身并没有重载,如果“到处都是”,则只有一个主体。@hakre规范称之为方法重载。你当然可以说它不是一个特别好的版本,但我想你不能说它根本不存在。@svick:我也没有说。但在我看来,OP询问的机会是关于方法重载的心理模型的。为了头发的分裂,我们可以