Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/.htaccess/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用逻辑的Typescript工厂类_Javascript_Typescript - Fatal编程技术网

Javascript 使用逻辑的Typescript工厂类

Javascript 使用逻辑的Typescript工厂类,javascript,typescript,Javascript,Typescript,我有一个typescript类继承了另一个。我想创建一个工厂类,它使用基本逻辑创建一个或另一个对象,但它不起作用 class CustomerCreator { static create(event: {name:string; dob: string}, type:string) { console.log('Log type' + typeof type); if (type === 'Basic') { console.log('basic custome

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

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)
这是客户的基本类:

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);
  }
}
customer creator旨在基于字符串比较创建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)

如果取消对最后一条print语句的注释,则代码不会编译。print语句还表明,尽管进行了字符串比较,但正在为客户1和客户2创建一个基本客户。我哪里出错了?

Typescript只有编译时的类型信息,但没有只有在运行时才知道的类型信息

CustomerCreator.create
的返回类型是
Customer | vipccustomer
,它被缩小为
Customer
,因此从该函数返回的所有内容都被ts编译器识别为
Customer
。这就是工厂模式的全部要点,即代码依赖于接口而不是类

如果您确实想让编译器知道
CustomerCreator.create
返回的确切类型,您可以尝试以下代码

type CreatorResult={
基本:客户,
VIP:VIP客户
}
类CustomerCreator{
静态创建(事件:{name:string;dob:string},类型:T):CreatorResult[T]{

虽然不建议这样做

但您的解决方案不起作用,因为
创建
工厂方法总是返回类型
客户
,因为
VIPCustomer
也是从
客户
派生的。此外,
创建
函数不仅只返回
客户
,而且还返回
客户|未定义d
因为您没有默认案例(当类型既不是
Basic
也不是
VIP
时)。我只会为每种类型的客户创建多个factory方法。在我的示例中,几乎没有共享代码或额外处理,factory模式变得无用

class CustomerCreator{
静态创建(事件:{name:string;dob:string}){
返回新客户(event.name、event.dob);
}
静态createVip(事件:{name:string;dob:string}){
返回新的VIPCustomer(event.name,event.dob);
}
}
console.log(Customer.c_类型);
控制台日志(VIPCustomer.c_类型);
const customer_1=CustomerCreator.createVip({name:'Pii',dob:'03/19'});
var customer_2=CustomerCreator.create({name:'Matthew',dob:'12/70'});
console.log(客户名称);
console.log(客户1.id);
console.log(customer\u 1.vip\u num)

为什么不建议这样做?这是对Typescript映射类型的滥用,并且向被调用方暴露了太多的细节更新了我的答案以包含解释