5

I have a class with an overloaded method (two versions).

One version takes no arguments. The second can take two.

class DFD {
...
    getEndDatetime(): string; 
    getEndDatetime(startTime?: string, duration?: number): string {
        if (!startTime || !duration) {
            return new Date(this.getEndDatetimePOSIX()).toLocaleString();
        } else {
            this.getEndDatetimePOSIX(startTime, duration);
            return new Date(this.getEndDatetimePOSIX(startTime, duration)).toLocaleString();
        }
    }
...
}

When I call this.getEndDateTime("8/11/2019, 11:42:17 PM", 5), TypeScript gives me an error, "Expected 0 arguments, but got 2." How do I satisfy TypeScript here?

I'm running Node v10.16.0, using TypeScript v3.5.2. I've tried switching the order of the overloads:

// Switch the order
...
    getEndDatetime(startTime?: string, duration?: number): string;
    getEndDatetime(): string { 
        ...
    }
...

TypeScript then highlights startTime and duration within the code, saying it can't find it.

I expected my first overload implementation to not throw any errors when called with two parameters, but it does.

Reading from elsewhere suggest my code should pass.

  • Why do you list the no-arg overload when both parameters are optional? – Jeff Bowman Aug 12 '19 at 04:10
  • just remove second declaration that have empty argument – Mochamad Arifin Aug 12 '19 at 04:21
  • @JeffBowman It's not essential after considering it. One reason might be documentation, but that's not practical in my case. Another reason is to emphasize the two implementations (the overloading syntax clarifies that it's 0 arguments or 2 arguments. Using only optional parameters makes it ambiguous as to whether you should use 0, 1, or 2 of the parameters). My basis for the question is now to understand TypeScript better. Why is it giving me the error when calling the method, when I've used seemingly valid overloading syntax. Are "no-parameter overloads" simply not allowed? –  Aug 12 '19 at 04:49

1 Answers1

2

It is likely because the transpiler is unable to determine which method you are wanting to call due to the two parameters signature being optional. In other words getEndDateTime() could refer to either signature you defined. To support this, you'll want to make startTime and duration no longer optional.

getEndDatetime(): string; 
getEndDatetime(startTime: string, duration: number): string; 
getEndDatetime(startTime?: string, duration?: number): string {
    if (!startTime || !duration) {
        return new Date(this.getEndDatetimePOSIX()).toLocaleString();
    } else {
        this.getEndDatetimePOSIX(startTime, duration);
        return new Date(this.getEndDatetimePOSIX(startTime, duration)).toLocaleString();
    }
}
Justin Collins
  • 320
  • 2
  • 7
  • Huh. So the last `getEndDatetime` is the actual implementation, and the first two are the signatures. So, you'll never have a method/function overload any case with less than three `funcNames` (or `getEndDate()`s). In my case, I only gave it one signature with no params. The second line in your code added the second option, making my method call with two arguments valid. –  Aug 12 '19 at 04:55