52
votes

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?

1
There is no function overloading in typescript, not even without generics. - Tamas Hegedus
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?? - user663031
@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<T1,T2> 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
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<number, string> 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. - user663031

1 Answers

42
votes

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
}