javascript - 使用逻辑的 Typescript 工厂类

标签 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)

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

最佳答案

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

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

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

type CreatorResult = {
    Basic: Customer,
    VIP: VIPCustomer
}

class CustomerCreator {
  static create<T extends 'Basic'| 'VIP'>(event: {name:string; dob: string}, type:T): CreatorResult[T] {

虽然不推荐

关于javascript - 使用逻辑的 Typescript 工厂类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55554104/

相关文章:

angular - NPM 包 : Referring to assets within the package

javascript - 在 javascript/typescript/nodejs 中创建可能的组合

javascript - 如何使用lastIndexOf在javascript中匹配url?

javascript - 我有一个问题 JSON stringify with javascript 中的循环结构

javascript - 使用 jQuery 折叠菜单和一个切换折叠的按钮

javascript - 如何创建一个 Handlebars 模板以在运行时在 Assemble 构建中编译?

javascript - 使用模块的 typescript

javascript - 如何在 Angular 6 的 div 上添加徽章?

javascript - 编辑 woocommerce Assets 的正确方法是什么?

javascript - 如何在其他页面上处于事件状态时更新其他页面标题?