0

I have created following interface for function overloading

interface IRequestObservableDelegate {
    (url: string | Request, options?: RequestOptionsArgs): Observable<Response>;
    (url: string | Request, body?: string, options?: RequestOptionsArgs): Observable<Response>;
}

My Idea is to pass a function of type above interface to another function

function DoSomething(cb:IRequestObservableDelegate,someCondition:boolean):void;

Following code works

const f1 = (u,o) => obsrevable; // dummy function
DoSomething(f1,somecond);

But this does not work

const f2 = (u,b,o) => obsrevable; // dummy function
DoSomething(f2,somecond);

Any Idea how to define overloaded function type

1
  • Whats the purpose of making both options and body optional but then define them twice? You can just use the second definition which would work also for the first example call. Commented Aug 14, 2017 at 13:45

2 Answers 2

4

When you provide multiple call signatures in the interface anything you try to assign to that interface must match all of the call signatures. Your assignment to f2 doesn't match the first signature because it has an extra parameter so you can't use it.

This does actually make sense, because any code using an object that implements the interface might call the function using the first signature and f2 doesn't know how to handle those calls.

What you might do instead would be to define two separate interfaces, one for each signature and then a type IRequestObservableDelegate with is the union of those two interfaces. Then f1 and f2 are each defined to hold the relevant restricted interface but either can still be passed to a function that accepts the union interface. That of course means the code using the union interface has to make assertions about the type of the callback function so you won't lose type safety when calling it.

interface IRequestSimpleObservableDelegate {
    (url: string | Request, options?: RequestOptionsArgs): Observable<Response>;
}
interface IRequestBodyObservableDelegate {
    (url: string | Request, body?: string, options?: RequestOptionsArgs): Observable<Response>;
}

type IRequestObservableDelegate = IRequestSimpleObservableDelegate | IRequestBodyObservableDelegate;

and now I think both assignments should work.

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

6 Comments

Thanks for replay do you know any construct which will help me to define overloaded function type (function type not function itself)
I think using a union of two separate types will work. See updated answer.
Isn't the union useless? The second function type definition is enough since both options and body are optional arguments and don't have to be passed :)
@Wernerson not useless if you want to use the parameters: const f1 = (u: string, o: RequestOptionsArgs) => dosomethingwith(o) won't match the second because body is the wrong type.
@Duncan I didn't mean useless but pointless^^; but why don't change the argument order and just define one type. Would be easier if you ask me :)
|
1

You are missing the optional parameters, you should do it like this:

const f1 = (u,o?) => obsrevable; // dummy function
DoSomething(f1,somecond);

const f2 = (u,b?,o?) => obsrevable; // dummy function
DoSomething(f2,somecond);

Comments

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.