Search code examples
typescriptclass

TypeScript: Multiple constructor implementations are not allowed


I have an Object where I use it in multiple services, and each one should take some parameters, so I create two constructors, but TypeScript did not allow me to do this. My example is:

class User {
    id: number;
    username: string;
    password: string;
    email: string;
    firstName: string;
    lastName: string;
    roles: string[];

    constructor(username: string, password: string){
        this.username = username;
        this.password = password;
    }

    constructor(id: number, username: string, firstname: string, lastname: string, roles: string[]){
        this.id = id;
        this.username= username;
        this.firstname= firstname;
        this.lastname= lastname;
        this.roles = roles;
    }
    //.. and maybe another constructor also
}

Is there a trick to solve this issue, please?


When I use the optional ? in constructors for example:

constructor(
    public id?: number,
    public username?: string,
    public email?: string,
    public password?: string,
    public firstName?: string,
    public lastName?: string,
    public roles?: string[]) {
}

and when I get my data from backend:

this.service.usersList().subscribe(users => {
  console.log(users);
  this.dataSource.data = users;
});

The roles is set in the password and not in the roles failed:

{
  "id": 1,
  "username": "user1",
  "email": "[email protected]",
  "password": [
    "USER",
    "MODR"
  ]
}

For that I'm not sure about this trick.


Maybe I was not precise, but I use this method to parse my data:

static fromJson(item: Object): any {
    return new User(
        item['id'],
        item['username'],
        item['email'],
        item['roles']
    );
}

For that, when I create a constructor with optional, it will set the attributes in order of my call.


Solution

  • You can't use multiple constructors, but you can add a few optional parameters and verify if it exists, like the following:

    class User {
        id: number;
        username: string;
        password: string;
        email: string;
        firstname: string;
        lastname: string;
        roles: string[];
        // The "?" says that its optional parameter
        constructor(id?: number, username?: string, firstname?: string,
            lastname?: string, roles?: string[], password?: string) {
            if (id) { // if id exists , you can implement the first constructor
                this.id = id;
                this.username = username;
                this.firstname = firstname;
                this.lastname = lastname;
                this.roles = roles;
            }
            if (password) { // if password exists : you can implement the second one
                this.username = username;
                this.password = password;
            }
        }
    }
    

    Your response should be like this before this works fine:

    static fromJson(item: Object): any {
        return new User({
            id : item['id'],
            username : item['username'],
            email : item['email'],
            roles : item['roles']
        });
    }
    

    So your constructor should be like this:

    constructor(user: any){
        if (user.id) { // if id exists , you can implement the first constructor
            this.id = user.id;
            this.username = user.username;
            this.firstname = user.firstname;
            this.lastname = user.lastname;
            this.roles = user.roles;
        }
        if (user.password) { // if password exists : you can implement the second one
            this.username = user.username;
            this.password = user.password;
        }
    }
    

    Or if you don't want to do that, you can set the response regarding the order, like this:

    static fromJson(item: Object): any {
        return new User(
            item['id'],
            item['username'],
            undefined,
            item['email'],
            undefined,
            undefined,
            item['roles']
        );
    }