Miguel Moura
Miguel Moura

Reputation: 39394

Similar methods with different parameters types in Typescript

I have the following Typescript methods:

authorize(permission: string, id?: number) : Observable<boolean> {

  return this.authorize(Permission[permission], id);

}

authorize(permission: Permission, id?: number) : Observable<boolean> {
  // authorization code
}

The first receives a permission of String type and converts it to Permission enum type.

Then calls the second method that accepts a permission of enum Permission type.

But I get the error:

Duplicate function implementation.

It seems Typescript is ignoring the parameters types.

Is there a way to overcome this?

Upvotes: 0

Views: 598

Answers (1)

jcalz
jcalz

Reputation: 328483

TypeScript's static type system including such type annotations is erased when compiled to JavaScript, which is what actually runs. So what you're proposing would end up compiling to something like (assuming ES2017)

class Thingy {
    authorize(permission, id) {
        return this.authorize(Permission[permission], id);
    }
    authorize(permission, id) {
        // authorization code
    }
}

In JavaScript, you can't have two methods with the same name... well, you can, but only the second one will ever be called. So this approach won't work.


What you need to do is have a single method whose implementation can handle both ways of calling it. TypeScript lets you represent different call signatures as overloads, but you still have to have a single implementation that does the work.

In your example, though, overloads are unneccessary, since you can represent the combination of both signatures as a single signature whose permission parameter is a union of string and Permission. And while I don't know what a Permission is (this is why minimum reproducible examples are useful), as long as it's not a type alias for string you can make a branching implementation that behaves the way you want:

authorize(permission: string | Permission, id?: number): Observable<boolean> {
  if (typeof permission === "string") {
  return this.authorize(Permission[permission], id);
} else {
  // authorization code
}

Okay, hope that helps; good luck!

Upvotes: 2

Related Questions