Voi*_*995 100 javascript operator-overloading typescript
有没有办法在TypeScript语言中进行方法重载?
我希望实现这样的目标:
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");
Run Code Online (Sandbox Code Playgroud)
这是我不想做的一个例子(我真的很讨厌在JS中重载hack的那部分):
class TestClass {
private someMethod_Overload_string(stringParameter: string): void {
// A lot of code could be here... I don't want to mix it with switch or if statement in general function
alert("Variant #1: stringParameter = " + stringParameter);
}
private someMethod_Overload_number_string(numberParameter: number, stringParameter: string): void {
alert("Variant #2: numberParameter = " + numberParameter + ", stringParameter = " + stringParameter);
}
private someMethod_Overload_string_number(stringParameter: string, numberParameter: number): void {
alert("Variant #3: stringParameter = " + stringParameter + ", numberParameter = " + numberParameter);
}
public someMethod(stringParameter: string): void;
public someMethod(numberParameter: number, stringParameter: string): void;
public someMethod(stringParameter: string, numberParameter: number): void;
public someMethod(): void {
switch (arguments.length) {
case 1:
if(typeof arguments[0] == "string") {
this.someMethod_Overload_string(arguments[0]);
return;
}
return; // Unreachable area for this case, unnecessary return statement
case 2:
if ((typeof arguments[0] == "number") &&
(typeof arguments[1] == "string")) {
this.someMethod_Overload_number_string(arguments[0], arguments[1]);
}
else if ((typeof arguments[0] == "string") &&
(typeof arguments[1] == "number")) {
this.someMethod_Overload_string_number(arguments[0], arguments[1]);
}
return; // Unreachable area for this case, unnecessary return statement
}
}
}
var testClass = new TestClass();
testClass.someMethod("string for v#1");
testClass.someMethod(12345, "string for v#2");
testClass.someMethod("string for v#3", 54321);
Run Code Online (Sandbox Code Playgroud)
svi*_*ick 144
根据规范,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);
}
}
Run Code Online (Sandbox Code Playgroud)
Fen*_*ton 31
更新清晰.TypeScript中的方法重载是一个有用的功能,因为它允许您使用需要表示的API为现有库创建类型定义.
但是,在编写自己的代码时,您可以使用可选参数或默认参数来避免重载的认知开销.这是方法重载的更易读的替代方法,并且还可以保持您的API诚实,因为您将避免使用不直观的排序创建重载.
TypeScript重载的一般规律是:
您通常可以使用可选或默认参数 - 或使用联合类型或使用一些面向对象来实现相同的功能.
实际问题要求超载:
someMethod(stringParameter: string): void {
someMethod(numberParameter: number, stringParameter: string): void {
Run Code Online (Sandbox Code Playgroud)
现在,即使在支持具有单独实现的重载的语言中(注意:TypeScript重载共享单个实现) - 程序员建议在排序中提供一致性.这将使签名:
someMethod(stringParameter: string): void {
someMethod(stringParameter: string, numberParameter: number): void {
Run Code Online (Sandbox Code Playgroud)
将stringParameter始终是必需的,所以先行.您可以将其写为有效的TypeScript重载:
someMethod(stringParameter: string): void;
someMethod(stringParameter: string, numberParameter: number): void;
someMethod(stringParameter: string, numberParameter?: number): void {
if (numberParameter != null) {
// The number parameter is present...
}
}
Run Code Online (Sandbox Code Playgroud)
但遵循TypeScript重载法则,我们可以删除过载签名,我们所有的测试仍然会通过.
someMethod(stringParameter: string, numberParameter?: number): void {
if (numberParameter != null) {
// The number parameter is present...
}
}
Run Code Online (Sandbox Code Playgroud)
如果您决定坚持原始订单,则重载将是:
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在有很多分支可以找出放置参数的位置,但如果你正在阅读这篇文章,你真的想保留这个顺序......但是等等,如果我们应用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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
当然,考虑到我们需要做的类型检查的数量......也许最好的答案就是有两种方法:
someMethod(stringParameter: string): void {
this.someOtherMethod(0, stringParameter);
}
someOtherMethod(numberParameter: number, stringParameter: string): void {
//...
}
Run Code Online (Sandbox Code Playgroud)
我希望.我也想要这个功能,但是TypeScript需要与没有重载方法的无类型JavaScript互操作.即如果从JavaScript调用重载方法,那么它只能被调度到一个方法实现.
关于codeplex的一些相关讨论.例如
https://typescript.codeplex.com/workitem/617
我仍然认为TypeScript应该生成所有if'ing和切换,所以我们不需要这样做.
| 归档时间: |
|
| 查看次数: |
62448 次 |
| 最近记录: |