TypeScript中的工厂返回类 [英] Factory returning classes in TypeScript

查看:67
本文介绍了TypeScript中的工厂返回类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据输入数据编写一个库;创建类并在主类中使用它们.

Wrote a library that, depending on the input data; creates classes and uses them inside a main class.

为了使代码更具可维护性和可读性,我将类生成逻辑移到了一个单独的文件中,该文件可以导出工厂函数.

To make the code more maintainable and readable, I've moved the class generation logic into a separate file that exports a factory function.

代码是在ES2015中编写的.现在,我要迁移到TypeScript.

Code was written in ES2015. Now I'm migrating to TypeScript.

这是一个伪示例:

export default function (foo:string) => {
    class A {
        value:string = foo + '-A';
    }

    return { A };
};

Main.ts

import factory from './factory';

export default class Main {
    private inner:any;
    constructor(foo:string) {
        this.inner = factory(foo);
    }
    get a() {
        return new this.inner.A();
    }
}

用法:

let main = new Main('bar');
console.log(main.a.value); // "bar-A"

问题:

  • TS编译器错误:
    模块的默认导出具有或正在使用私有名称'A'.
  • Main 类中无法将getter a 的类型定义为 A (例如, get a():A {...}
  • Problems:

    • TS compiler error:
      Default export of the module has or is using private name 'A'.
    • Cannot define the type of the getter a as A in Main class (e.g. get a():A { ... }
    • 您将如何解决(将工厂类保存在单独的文件中)?还是应该更改设计模式?

      How would you resolve this (keeping the factory classes in a separate file)? Or should I change the design pattern?

      推荐答案

      诸如此类的事情

      export interface Base {}
      
      export interface IA extends Base {
          value: string;
      }
      
      export type Builders = {
          [name: string]: { new <T extends Base>(): T };
      }
      
      export function factory(foo: string): Builders {
          class A implements IA {
              value:string = foo + '-A';
          }
      
          return { A };
      };
      

      并且:

      import { factory, IA, Builders } from './Factory';
      
      export default class Main {
          private inner: Builders;
      
          constructor(foo:string) {
              this.inner = factory(foo);
          }
      
          get a():IA {
              return new this.inner.A() as IA;
          }
      }
      


      编辑

      factory.ts 怎么了?

      export class Base {}
      
      export type Builders = {
          [name: string]: { new <T extends Base>(): T };
      }
      
      class A extends Base {
          value: string;
      
          constructor();
          constructor(foo: string);
          constructor(foo?: string) {
              super();
              this.value = foo + "-A";
          }
      }
      
      // more classes...
      
      export function factory(foo: string): Builders {
          return { A: A.bind(A, foo) };
      };
      

      与您所做的基本上相同,只是这些类未在该类内部定义,并且已导出,因此不需要我建议的接口.
      同样,通过这种方式,所有类仅被评估一次,而不是每次调用 factory 函数时都会被评估.

      It's basically the same as what you did, just that the classes are not defined inside the class, and are exported so no need for the interfaces I suggested.
      Also, this way all the classes will only be evaluated once and not every time the factory function is invoked.

      这篇关于TypeScript中的工厂返回类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆