undefined
undefined

Reputation: 6884

Typescript interface method overload doesn't work

I have the following code:

class A { }

class B { }

class C { }

interface Builder {
    build(paramOne: A): string;
    build(paramOne: B, paramTwo: C): number;
}

class Test implements Builder {
    build(a: A) {
      return 'string';
    }
}

Why I'm getting an error from typescript on the build() method? I'm expecting that typescript will know that when I pass only one param with type A, it should return a string.

Upvotes: 2

Views: 1824

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 250366

The interface implementation will need to have the public overloads that your interface does. To specify an actual implementation for the method you need to use an extra implementation signature :

class A { p: string }

class B { b: string}

class C { c: string}

interface Builder {
    build(paramOne: A): string;
    build(paramOne: B, paramTwo: C): number;
}

class Test implements Builder {

    build(paramOne: A): string;
    build(paramOne: B, paramTwo: C): number;
    build(paramOne: A|B, paramTwo?: C) : string | number {
    return 'string';
    }
}

new Test().build(new A()) // return string 
new Test().build(new B(), new C()) // returns number
new Test().build(new A(), new C())  // error implementation signature is not callable directly 

You can implement the function as a member field instead of a method if you want to avoid specifying the overloads again, but this is less safe (I had to use any as the return type to get the new function to be compatible with the overloads). And there are performance implications to using a field (which is assigned on the instance) instead of a method (which is assigned on the prototype)

class Test implements Builder {

    build: Builder ['build'] = function (this: Test, paramOne: A|B, paramTwo?: C) : any {
        return 'string';

    }
}

Upvotes: 1

Related Questions