77

I have defined the following two function signatures in the same Typescript class, i.e.,

public emit<T1>(event: string, arg1: T1): void {}

and

public emit<T1,T2>(event: string, arg1: T1, arg2: T2): void {}

However when transpiling the typescript I get the following error

error TS2393: Duplicate function implementation.

I thought you could overload functions in typescript providing the number of parameters in the function signature were different. Given that the above signatures have 2 and 3 parameters respectively, why am I getting this transpilation error?

James B
  • 8,975
  • 13
  • 45
  • 83
  • 1
    There is no function overloading in typescript, not even without generics. – Tamas Hegedus Sep 25 '16 at 17:44
  • 10
    Please read the documentation on overloading more closely. Overloading does not mean you can provide multiple **implementations**; it means you you can provide multiple **signatures**, with a single implementation. But in this case why are you not simply writing `arg2?`? –  Sep 25 '16 at 17:46
  • @torazaburo. I'm trying to ensure type safety through generics. If I use `arg2?` I'll still have to provide the generic type `T2` in `emit` even though I may not actually be using `T2`. I guess I'm trying to achieve something similar to c#'s `Func` and `Action` delegate signatures. But there could be a better way. – James B Sep 25 '16 at 17:54
  • 2
    If you are referring to providing the generic type `T2` in the **definition** of the function, this harms nothing. If are referring to **calling** the function, providing any type, as in `emit` shouldn't be necessary since types will be picked up from the types of the arguments. Anyway, if necessary, write out the two declarations with no body (just a semi-colon), then write **one** implementation that somehow checks for the presence of `arg2`, or perhaps assigns it a default value. –  Sep 25 '16 at 18:03
  • Does this answer your question? [TypeScript function overloading](https://stackoverflow.com/questions/13212625/typescript-function-overloading) – Vega Jul 22 '22 at 10:49

3 Answers3

64

I'm assuming your code looks like this:

public emit<T1>(event: string, arg1: T1): void {}
public emit<T1,T2>(event: string, arg1: T1, arg2: T2): void {}
public emit(event: string, ...args: any[]): void {
    // actual implementation here
}

The problem is that you have {} after the first 2 lines. This actually defines an empty implementation of a function, i.e. something like:

function empty() {}

You only want to define a type for the function, not an implementation. So replace the empty blocks with just a semi-colon:

public emit<T1>(event: string, arg1: T1): void;
public emit<T1,T2>(event: string, arg1: T1, arg2: T2): void;
public emit(event: string, ...args: any[]): void {
    // actual implementation here
}
Mattias Buelens
  • 19,609
  • 4
  • 45
  • 51
  • 12
    When you overload in TypeScript, you only have one implementation with multiple signatures. See https://stackoverflow.com/questions/13212625/typescript-function-overloading – Matthew K Jun 25 '18 at 16:08
  • 3
    So if that three function contains different logics? – Prashant Pimpale Feb 01 '19 at 07:57
  • There are three signatures, but just one implementation. If you need different logic depending on what signature was used, you'll need to add some extra checks inside your implementation. For example, you could check `args.length` to figure out if only `arg1` was passed, or if both `arg1` and `arg2` were passed. – Mattias Buelens Feb 05 '19 at 16:00
  • 1
    These are all void functions. But what to do with generic return values. For example, what if the return type of the first overload is `T1` (or `string`) while the second overload return type if `T2`? – Ark-kun Jun 28 '22 at 02:03
13
export {}

Just add this line at the top of the typescript file

Coders_ Ground
  • 147
  • 1
  • 3
  • 4
    It works. The question ist: Why? :-) – Andreas Susewind Jan 29 '22 at 17:06
  • "Another cause of the error is having a glitch due to legacy script files. If you only have a single definition for the function in the file, add the export {} line to your file to make it an ES Module" From [this blog](https://bobbyhadz.com/blog/typescript-duplicate-function-implementation) – aditya tyagi Jun 19 '22 at 15:42
13

Because you open both Typescript and JavaScript file in the same window in IDE you can solve this problem with three ways:

First Solution:

Open typescript file only or JavaScript file only

Second solution - run this command:

tsc --init

This command will create tsconfig.json file for typescript configuration

Last Solution write

export{}

In the top of the file

Eng_Farghly
  • 1,987
  • 1
  • 23
  • 34