Typescript工厂类导致缺少属性

问题描述 投票:0回答:2

我正在寻找使用Typescript创建一个工厂类 - 一个返回另一个类的对象的类。

我有一个类,由另一个类扩展:

class Customer {
  static member = true;
  id = Math.random().toString(36).substr(2, 9);
  static c_type = "Basic Customer";

  makeTransaction():string {
    var transaction_id = Math.random().toString(36).substr(2, 9);
    console.log(this.constructor.toString().split ('(' || /s+/)[0].split (' ' || /s+/)[1]);
    return transaction_id;
  }

  constructor(public name:string, public dob:string) {}

}

class VIPCustomer extends Customer{
  vip_num = Math.random().toString(36).substr(2, 9);
  vip_discount:number;
  static c_type = "VIP Customer";

}

我还创建了工厂类,用于返回对象:

class CustomerCreator {
  static create(event: Customer, type:string) {
    if (type == 'Basic') {
      return new Customer(event.name, event.dob);
    }
    if (type == 'VIP') {
      return new VIPCustomer(event.name, event.dob);
    }

  }
}

我能够像这样创建对象:

var customer_2 = new Customer('Matthew', '12/70');

但是,当我尝试使用创建者时:

const customer_1 = CustomerCreator.create({name:'Pii', dob:'03/19'}, 'Basic');

我收到以下错误:

Argument of type '{name: string, dob: string}' is not assignable to parameter of type 'Customer'.
Property 'id' is missing in type '{name:string, dob:string}'

如果我在构造函数中包含所有字段和方法,它就可以工作。但是,有没有办法解决这个问题?

更新:

我按照建议将id定义移动到构造函数中,但它并没有解决我的问题。

class Customer {
  static member = true;
  id:string;
  static c_type = "Basic Customer";

  makeTransaction():string {
    var transaction_id = Math.random().toString(36).substr(2, 9);
    console.log(this.constructor.toString().split ('(' || /s+/)[0].split (' ' || /s+/)[1]);
    return transaction_id;
  }

  constructor(public name:string, public dob:string) {
    this.id = Math.random().toString(36).substr(2, 9);
  }

}
javascript typescript factory
2个回答
0
投票

问题似乎是你试图在声明时设置id。你需要在构造函数中设置id,它将为每个新创建的customer对象设置

class Customer {
  static member = true;
  id = string;
  static c_type = "Basic Customer";

  makeTransaction():string {
    var transaction_id = Math.random().toString(36).substr(2, 9);
    console.log(this.constructor.toString().split ('(' || /s+/)[0].split (' ' || /s+/)[1]);
    return transaction_id;
  }

  constructor(public name:string, public dob:string) {
    this.id = Math.random().toString(36).substr(2, 9)
  }

}

这看起来像一个有趣的读https://github.com/tc39/proposal-class-public-fields/issues/2


0
投票

所以你的CustomerCreator.create签名是:

static create(event: Customer, type:string): Customer;

当你写它时,它需要一个客户(event)和一个字符串(type),它返回一个Customer

你用以下方法调用它:

const customer_1 = CustomerCreator.create({name:'Pii', dob:'03/19'}, 'Basic');

这导致错误:

“{name:string,dob:string}”类型的参数不能分配给“Customer”类型的参数。类型'{name:string,dob:string}'中缺少属性'id'

由于您提供以下对象作为event参数:

{name:'Pii', dob:'03/19'}

这不符合Customer类型,因为它没有id,但create方法的签名需要Customer用于事件参数。

我认为你应该在create定义中使用另一种类型,例如:

type CustomerEvent {
  name: string;
  dob: string;
}

class CustomerCreator {
  static create(event: CustomerEvent, type:string) {
    if (type == 'Basic') {
      return new Customer(event.name, event.dob);
    }
    if (type == 'VIP') {
      return new VIPCustomer(event.name, event.dob);
    }

  }
}

这将解决错误。

更新

CustomerEvent就是一个例子。您也可以在方法定义中动态定义类型:

static create(event: {id: string, name: string}, type:string) ...

关键是你的原始问题是由于传递给create的对象不符合Customer类型。

创建一个新类型CustomerEvent的决定 - 或类似的 - 很大程度上取决于那种对象将在你的应用程序的很多部分传递或不传递。

© www.soinside.com 2019 - 2024. All rights reserved.