29

I created the following class:

export class MyItem {
  public name: string;
  public surname: string;
  public category: string;
  public address: string;

  constructor();
  constructor(name:string, surname: string, category: string, address?: string);
  constructor(name:string, surname: string, category: string, address?: string) {
    this.name = name;
    this.surname = surname;
    this.category = category;
    this.address = address;
  }
}

I get the following error:

Overload signature is not compatible with function implementation

I tried several ways to overload the constructor, the last one I tried is that I posted above (that I get from here).

But I still get the same error. What's wrong with my code?

peterh
  • 11,875
  • 18
  • 85
  • 108
smartmouse
  • 13,912
  • 34
  • 100
  • 166

1 Answers1

45

You get that compilation error because the signature of the implementation function does not satisfy the empty constructor you declared.
As you want to have the default constructor, it should be:

class MyItem {
    public name: string;
    public surname: string;
    public category: string;
    public address: string;

    constructor();
    constructor(name:string, surname: string, category: string, address?: string);
    constructor(name?: string, surname?: string, category?: string, address?: string) {
        this.name = name;
        this.surname = surname;
        this.category = category;
        this.address = address;
    }
}

(code in playground)

Notice that all of the arguments in the actual implementation are optional and that's because the default constructor has no arguments.
This way the implementing function has a signature that satisfies both other signatures.

But you can then just have that single signature with no need to declare the other two:

class MyItem {
    public name: string;
    public surname: string;
    public category: string;
    public address: string;

    constructor(name?: string, surname?: string, category?: string, address?: string) {
        this.name = name;
        this.surname = surname;
        this.category = category;
        this.address = address;
    }
}

(code in playground)

The two are equivalent.

Nitzan Tomer
  • 155,636
  • 47
  • 315
  • 299
  • They might not be with typechecking. – Someone Mar 14 '22 at 20:55
  • The two are definitely not equivalent. The first overload doesn’t take any parameters, so all use some default value (assuming that there may be other logic not shown in this reduced use case), while the second overload requires that name, surname, and category all be defined, but address is optional. Your "combined" version is completely different, allowing name to be undefined while surname is defined, or perhaps name undefined, surname defined, and category undefined, or any other number of incompatible call signatures. In no way is it equivalent. – Eric Ferreira Jun 20 '23 at 01:57