Typescript工厂类使用逻辑

时间:2019-04-06 22:44:15

标签: javascript typescript

我有一个Typescript类继承了另一个。我想创建一个工厂类,该工厂类使用基本逻辑创建一个或另一个对象,但是它不起作用。

这是客户的基本课程:

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

}

此类可扩展客户以创建VIP客户:

class VIPCustomer extends Customer{
  vip_num:string;
  vip_discount:number;
  static c_type = "VIP Customer";
  constructor(public name:string, public dob:string) {
    super(name, dob);
    this.vip_num = Math.random().toString(36).substr(2, 9);
  }
}

客户创建者旨在基于字符串比较来创建VIP客户或常规客户,但此方法不起作用。

class CustomerCreator {
  static create(event: {name:string; dob: string}, type:string) {
    console.log('Log type' + typeof type);
    if (type === 'Basic') {
      console.log('basic customer created');
      return new Customer(event.name, event.dob);
    }
    if (type === 'VIP') {
      console.log('basic customer created');
      return new VIPCustomer(event.name, event.dob);
    }
  }
}
console.log(Customer.c_type);
console.log(VIPCustomer.c_type);
const customer_1 = CustomerCreator.create({name:'Pii', dob:'03/19'}, 'VIP');
var customer_2 = CustomerCreator.create({name:'Matthew', dob:'12/70'}, 'Basic');

//accessing an attribute
console.log(customer_1.name);
console.log(customer_1.id);
//console.log(customer_1.vip_num)

如果取消注释最后一个打印语句,则代码不会编译。打印语句还表明尽管有字符串比较,也正在为客户1和2创建一个基本客户。我要去哪里错了?

2 个答案:

答案 0 :(得分:2)

Typescript仅具有编译时的类型信息,而没有仅在运行时知道的类型信息。

CustomerCreator.create的返回类型为Customer|VIPCustomer,其范围缩小为Customer,因此从该函数返回的所有内容都将被{ts1}识别为ts编译器。这就是Factory模式的全部要点,您的代码依赖于接口而不是类

如果您真的想让编译器知道Customer返回的确切类型,则可以尝试使用以下代码

CustomerCreator.create

尽管不建议这样做

答案 1 :(得分:1)

您的解决方案无效,因为create的工厂方法总是返回类型Customer,因为VIPCustomer也是从Customer派生的。另外,您的create函数不仅返回Customer,而且还返回Customer | undefined,因为您没有默认的大小写(类型既不是Basic也不是VIP)。我只是为每种类型的客户创建多个工厂方法。在我的示例中,几乎没有共享的代码或额外的处理,工厂模式变得无用。

class CustomerCreator {
    static create(event: { name: string; dob: string }) {
        return new Customer(event.name, event.dob);
    }

    static createVip(event: { name: string; dob: string }) {
        return new VIPCustomer(event.name, event.dob);
    }
}
console.log(Customer.c_type);
console.log(VIPCustomer.c_type);
const customer_1 = CustomerCreator.createVip({ name: 'Pii', dob: '03/19' });
var customer_2 = CustomerCreator.create({ name: 'Matthew', dob: '12/70' });

console.log(customer_1.name);
console.log(customer_1.id);
console.log(customer_1.vip_num)