2

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.

6
  • What error do you get and on which build? You have 3 of them Commented Oct 2, 2018 at 5:39
  • Because interface is not fully implemented. Commented Oct 2, 2018 at 5:39
  • stackblitz.com/edit/typescript-77rou1 Commented Oct 2, 2018 at 5:43
  • stackblitz.com/edit/typescript-1u1g47 Commented Oct 2, 2018 at 6:01
  • @AlekseyL. Thanks. So I need to repeat this on every class that implements Builder? Commented Oct 2, 2018 at 6:03

1 Answer 1

1

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';

    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

So I need to repeat this on every class that implements Builder?
@undefined yes you do unfortunately .. there is a way to do it if you use a function field instead of a method.. i'll add

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.