TypeScript 函数重载

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13212625/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-11 00:55:35  来源:igfitidea点击:

TypeScript function overloading

typescriptoverloading

提问by Klaus Nji

Section 6.3 of the TypeScript language spec talks about function overloading and gives concrete examples on how to implement this. However if I try something like this:

TypeScript 语言规范的第 6.3 节讨论了函数重载,并给出了如何实现它的具体示例。但是,如果我尝试这样的事情:

export class LayerFactory { 

    constructor (public styleFactory: Symbology.StyleFactory) { }

    createFeatureLayer (userContext : Model.UserContext, mapWrapperObj : MapWrapperBase) : any {           
         throw "not implemented";
    }                 

    createFeatureLayer(layerName : string, style : any) : any {
        throw "not implemented";
     }        

}

I get a compiler error indicating duplicate identifier even though function parameters are of different types. Even if I add an additional parameter to the second createFeatureLayer function, I still get a compiler error. Ideas, please.

即使函数参数的类型不同,我也会收到指示重复标识符的编译器错误。即使我向第二个 createFeatureLayer 函数添加了额外的参数,我仍然会收到编译器错误。想法,请。

采纳答案by S. Ravi Kiran

This may be because, when both functions are compiled to JavaScript, their signature is totally identical. As JavaScript doesn't have types, we end up creating two functions taking same number of arguments. So, TypeScript restricts us from creating such functions.

这可能是因为,当两个函数都编译为 JavaScript 时,它们的签名完全相同。由于 JavaScript 没有类型,我们最终创建了两个带有相同数量参数的函数。所以,TypeScript 限制我们创建这样的函数。

TypeScript supports overloading based on number of parameters, but the steps to be followed are a bit different if we compare to OO languages. In answer to another SO question, someone explained it with a nice example: Method overloading?.

TypeScript 支持基于参数数量的重载,但是如果我们与面向对象语言相比,要遵循的步骤有点不同。在回答另一个 SO 问题时,有人用一个很好的例子解释了它:方法重载?.

Basically, what we are doing is, we are creating just one function and a number of declarations so that TypeScript doesn't give compile errors. When this code is compiled to JavaScript, the concrete function alone will be visible. As a JavaScript function can be called by passing multiple arguments, it just works.

基本上,我们正在做的是,我们只创建一个函数和一些声明,这样 TypeScript 就不会出现编译错误。当这段代码被编译成 JavaScript 时,具体的功能就会单独显示出来。由于可以通过传递多个参数来调用 JavaScript 函数,因此它可以正常工作。

回答by Fenton

When you overload in TypeScript, you only have one implementation with multiple signatures.

当您在 TypeScript 中重载时,您只有一个具有多个签名的实现。

class Foo {
    myMethod(a: string);
    myMethod(a: number);
    myMethod(a: number, b: string);
    myMethod(a: any, b?: string) {
        alert(a.toString());
    }
}

Only the three overloads are recognized by TypeScript as possible signatures for a method call, not the actual implementation.

TypeScript 仅将三个重载识别为方法调用的可能签名,而不是实际实现。

In your case, I would personally use two methods with different names as there isn't enough commonality in the parameters, which makes it likely the method body will need to have lots of "ifs" to decide what to do.

在你的情况下,我个人会使用两个不同名称的方法,因为参数没有足够的共性,这使得方法主体可能需要有很多“ifs”来决定要做什么。

TypeScript 1.4

打字稿 1.4

As of TypeScript 1.4, you can typically remove the need for an overload using a union type. The above example can be better expressed using:

从 TypeScript 1.4 开始,您通常可以使用联合类型消除对重载的需要。上面的例子可以更好地表达:

myMethod(a: string | number, b?: string) {
    alert(a.toString());
}

The type of ais "either stringor number".

类型a是“要么stringnumber”。

回答by Drew Noakes

You can declarean overloaded function by declaring the function as having a type which has multiple invocation signatures:

您可以通过将函数声明为具有多个调用签名的类型来声明重载函数:

interface IFoo
{
    bar: {
        (s: string): number;
        (n: number): string;
    }
}

Then the following:

然后如下:

var foo1: IFoo = ...;

var n: number = foo1.bar('baz');     // OK
var s: string = foo1.bar(123);       // OK
var a: number[] = foo1.bar([1,2,3]); // ERROR

The actual definitionof the function must be singular and perform the appropriate dispatching internally on its arguments.

函数的实际定义必须是单数的,并在内部对其参数执行适当的分派。

For example, using a class (which could implement IFoo, but doesn't have to):

例如,使用一个类(它可以实现IFoo,但不是必须的):

class Foo
{
    public bar(s: string): number;
    public bar(n: number): string;
    public bar(arg: any): any 
    {
        if (typeof(arg) === 'number')
            return arg.toString();
        if (typeof(arg) === 'string')
            return arg.length;
    }
}

What's interesting here is that the anyform is hiddenby the more specifically typed overrides.

有趣的是,any表单被更具体的类型覆盖隐藏了。

var foo2: new Foo();

var n: number = foo2.bar('baz');     // OK
var s: string = foo2.bar(123);       // OK
var a: number[] = foo2.bar([1,2,3]); // ERROR

回答by mtyson

As a heads up to others, I've oberserved that at least as manifested by TypeScript compiled by WebPack for Angular 2, you quietly get overWRITTEN instead of overLOADED methods.

作为对其他人的提醒,我观察到至少正如 WebPack 为 Angular 2 编译的 TypeScript 所表明的那样,您悄悄地得到了覆盖而不是重载的方法。

myComponent {
  method(): { console.info("no args"); },
  method(arg): { console.info("with arg"); }
}

Calling:

调用:

myComponent.method()

seems to execute the method with arguments, silently ignoring the no-arg version, with output:

似乎使用参数执行该方法,静默忽略无参数版本,输出:

with arg

回答by Willem van der Veen

Function overloading in typescript:

打字稿中的函数重载:

According to Wikipedia, (and many programming books) the definition of method/function overloading is the following:

根据维基百科(和许多编程书籍)方法/函数重载的定义如下:

In some programming languages, function overloading or method overloading is the ability to create multiple functions of the same name with different implementations. Calls to an overloaded function will run a specific implementation of that function appropriate to the context of the call, allowing one function call to perform different tasks depending on context.

在某些编程语言中,函数重载或方法重载是创建多个具有不同实现的同名函数的能力。对重载函数的调用将运行适合调用上下文的该函数的特定实现,允许一个函数调用根据上下文执行不同的任务。

In typescript we cannot have different implementations of the same function that are called according to the number and type of arguments. This is because when TS is compiled to JS, the functions in JS have the following characteristics:

在打字稿中,我们不能根据参数的数量和类型调用同一函数的不同实现。这是因为 TS 编译成 JS 时,JS 中的函数有以下特点:

  • JavaScript function definitions do not specify data types for their parameters
  • JavaScript functions do not check the number of arguments when called
  • JavaScript 函数定义不为其参数指定数据类型
  • JavaScript 函数在调用时不检查参数的数量

Therefore, in a strict sense, one could argue that TS function overloading doesn't exists. However, there are things you can do within your TS code that can perfectly mimick function overloading.

因此,从严格意义上讲,可以认为不存在 TS 函数重载。但是,您可以在 TS 代码中做一些可以完美模仿函数重载的事情。

Here is an example:

下面是一个例子:

function add(a: number, b: number, c: number): number;
function add(a: number, b: number): any;
function add(a: string, b: string): any;

function add(a: any, b: any, c?: any): any {
  if (c) {
    return a + c;
  }
  if (typeof a === 'string') {
    return `a is ${a}, b is ${b}`;
  } else {
    return a + b;
  }
}

The TS docs call this method overloading, and what we basically did is supplying multiple method signatures (descriptions of possible parameters and types) to the TS compiler. Now TS can figure out if we called our function correctly during compile time and give us an error if we called the function incorrectly.

TS 文档称此方法为重载,我们所做的基本上是向 TS 编译器提供多个方法签名(可能的参数和类型的描述)。现在 TS 可以确定我们在编译时是否正确调用了我们的函数,如果我们错误地调用了函数,就会给我们一个错误。

回答by ford04

What is function overloading?

什么是函数重载?

Function overloading or method overloading is the ability to create multiple functionsof the same namewith different implementations(Wikipedia)

函数重载或方法重载是创建多个具有不同实现同名函数的能力(维基百科

Class method and function declaration overload types are similar. We use terms synonymously here.

类方法和函数声明重载类型类似。我们在这里使用同义词。

// difference class method and function:
class Foo { 
  bar() {} // method
} 
function bar() {} // function


What is function overloading in JS?

什么是JS中的函数重载?

A function overload is not possible in JS - the last function declaration is taken:

JS 中不可能有函数重载——采用最后一个函数声明:

function foo(a1, a2) { return `${a1}, ${a2}` }
function foo(a1) { return `${a1}` }
foo(42, "foo") // "42"

... and in TS?

......在TS中?

These overloadsare a compile-timeconstruct with no impact on the JS runtime:

这些重载是一个编译时构造,对 JS 运行时没有影响:

function foo(s: string): string // overload #1 of foo
function foo(s: string, n: number): number // overload #2 of foo
function foo(s: string, n?: number): string | number {/* ... */} // foo implementation

A duplicate implementation error is triggered, if you copy above JS code (safer). TS chooses the first fitting overload in top-down order, so overloads are sorted from most specific to most broad.

如果复制上面的 JS 代码(更安全),则会触发重复的实现错误。TS 按自上而下的顺序选择第一个拟合重载,因此重载从最具体到最广泛排序。



A more complex method overload example

一个更复杂的方法重载示例

class LayerFactory {
    createFeatureLayer(a1: string, a2: number): string
    createFeatureLayer(a1: number, a2: boolean, a3: string): number
    createFeatureLayer(a1: string | number, a2: number | boolean, a3?: string)
        : number | string { /*... your implementation*/ }
}

const fact = new LayerFactory()
fact.createFeatureLayer("foo", 42) // string
fact.createFeatureLayer(3, true, "bar") // number

These very different overloads are possible, because the the function implementation is compatible to all overload signatures - enforced by the compiler.

这些非常不同的重载是可能的,因为函数实现与所有重载签名兼容 - 由编译器强制执行。

Further links:

更多链接: