【问题标题】:TypeScript: Multiple constructor implementations are not allowedTypeScript:不允许多个构造函数实现
【发布时间】:2020-07-24 00:59:13
【问题描述】:

我有一个对象,我在多个服务中使用它,每个都应该接受一些参数,所以我创建了两个构造函数,但 TypeScript 不允许我这样做,我的例子是:

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
}

请问有什么技巧可以解决这个问题吗?


例如,当我在构造函数中使用 Optional ? 时:

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

当我从后端获取数据时:

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

roles 设置在密码中而不是角色中失败:

{
  "id": 1,
  "username": "user1",
  "email": "user1@email.com",
  "password": [
    "USER",
    "MODR"
  ]
}

对此我不确定。


也许我不准确,但我使用这种方法来解析我的数据:

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

为此,当我创建一个可选的构造函数时,它将按照我的调用顺序设置属性。

【问题讨论】:

  • Typescript 只允许 1 个构造函数。您可以使用? 可选参数。哪些字段始终是必填字段?
  • @NicholasK 我知道打字稿只允许一个构造函数,但在我的情况下我需要多个构造函数,如果我使用? 作为可选,它在某些情况下会失败
  • 您可以使用optional parameters,并验证是否存在实现两个构造函数之一所需的参数,请参阅下面的答案
  • 解释那些案例,以便我们给你一个更好的答案。
  • 你不能在 JS 中对同一个方法有多个实现。但是,您可以在 TypeScript even for constructors 中为它们声明重载签名。

标签: angular typescript


【解决方案1】:

你不能使用多个构造函数,但你可以添加一些可选参数并验证它是否存在,如下所示:

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;
        }
    }
}

在此之前您的回复应该是这样的:

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

所以你的构造函数应该是这样的:

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;
    }
}

或者如果您不想这样做,您可以设置有关订单的响应,如下所示:

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

【讨论】:

  • 谢谢@Aymen,当我尝试您的解决方案时,我遇到了在姓氏中设置角色而不是在角色中失败{ "id": 1, "username": "user1", "firstName": "user1@email.com", "lastName": [ "USER", "MODR" ] }
  • 在后端我发送了一个拥有不同属性的对象,但是当它来到前端时,对象设置不正确。
  • 好的,我修好了,我在构造函数中添加角色
  • okey 然后,您只需将其添加到您的第一个 if 条件中,并使用 ? 标记添加到构造函数参数中
  • 对不起,但正如我所说,角色是在 lastName 中设置的,而不是在角色中,我不明白为什么 typescript 会这样做,这不是你的错误,但你的解决方案不起作用
【解决方案2】:

我知道这是很老的帖子,但我想分享我的建议:

export class A {
   constructor() {
      //something here
   }
   secondConstructor() {
      // something here
      return this;
   }
}

然后你像这样使用:

const a = new A();
const a2 = new A().secondConstructor();

【讨论】:

    【解决方案3】:

    我找到了解决办法:

    会发生什么?

    当你创建一个带有可选参数的构造函数并尝试调用这个构造函数时,它会按照调用的顺序设置属性,当我调用时:

    new User(
        item['id'],
        item['username'],
        item['email'],
        item['roles']
    );
    

    名字或密码中设置的角色。

    解决方案

    为了解决这个问题,需要在constructor中更改顺序或参数:

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

    或者如果您不更改顺序,只需使用undefined 例如:

    new User(
        item['id'],
        item['username'],
        undefined,
        item['email'],
        undefined,
        undefined,
        item['roles']
    );
    

    直到你到达你的属性的位置。

    【讨论】:

      猜你喜欢
      • 2019-07-03
      • 2019-02-21
      • 2017-04-23
      • 1970-01-01
      • 2019-07-04
      • 1970-01-01
      • 2011-09-12
      • 1970-01-01
      • 2019-10-27
      相关资源
      最近更新 更多