0

I'm trying to call a function expression like this:

export default interface IUserManager {
    deleteUser: ((userId: string) => Promise<void>) | ((userName: string, userSurname: string, city: string) => Promise<void>
}

from a class which holds the interface instance:

import MyUserManager from "path/to/IUserManager.ts"

class CompanyProcessor {
    private myUserManager: IUserManager;

    public constructor() {
        this.myUserManager = new MyUserManager(); // MyUserManager implements IUserManager
    }

    public async deleteUser(userId: string): Promise<void> {
        await this.myUserManager.deleteUser(userid); // Expected 3 argument, but got 1. ts(2554)
    }
}

In VSCode, hovering over the function expression in IUserManager shows the tuple of functions. Hovering over the function call in CompanyProcessor shows only the largest function in the tuple. I've also noticed that making "userSurname" and "city" optional does work in CompanyProcessor, but doing this breaks the requirement of 3 properties, making it possible to only provide the first 2. It also does not seem to use the other functions in the tuple this way.

Example hover pop-up in the original situation:

(property) IUserManager.deleteUser: (userName: string, userSurname: string, city: string) => Promise<void>

Example hover pop-up when "userSurname" and "city" are optional:

(property) IUserManager.deleteUser: (userName: string, userSurname?: string, city?: string) => Promise<void> (+1 overload)

My TypeScript version is 4.7.4

4
  • You declared IUserManager, but using MyUserManager, is it ok? If you implements IUserManager in MyUserManager, there are no errors: shorturl.at/knUZ1 Commented Aug 17, 2022 at 13:45
  • Oh you're right, my example code wasn't entirely correct. I'll correct the example, as I am referring to the IUserManager function from CompanyProcessor. Commented Aug 17, 2022 at 13:50
  • @Eugene But when there is only one argument (attempting to use the first "overload") it does not work. Commented Aug 17, 2022 at 13:58
  • Yeah I noticed I put something backwards, for that my apologies. The problem isn't with the leftmost function, but that it apparently always assumes the shape of the largest function expression. It does not accept deleteUser(userId) in this shape. Commented Aug 17, 2022 at 13:59

1 Answer 1

1

You shouldn't use a union of functions. Instead you can use call signatures to describe a function with multiple overloads:

deleteUser: {
    (userId: string): Promise<void>;
    (userName: string, userSurname: string, city: string): Promise<void>;
};
Sign up to request clarification or add additional context in comments.

1 Comment

I tried this and it definitely is the way to go. Thank you!

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.