Typescript工厂类导致缺少属性

时间:2019-03-14 09:14:41

标签: javascript typescript factory

我正在寻找使用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);
  }

}

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

因此,您对CustomerCreator.create的签名是:

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

如您所写,它需要一个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或类似的决定在很大程度上取决于该类型的对象是否会在应用程序的很多部分中传递。