在工厂函数之外公开本地 TypeScript 类的类型

Posted

技术标签:

【中文标题】在工厂函数之外公开本地 TypeScript 类的类型【英文标题】:Expose type of local TypeScript class outside factory function 【发布时间】:2016-01-18 00:38:49 【问题描述】:

我想使用工厂来管理我的一些依赖注入,因此我在函数内部创建了一个本地类。我使用的 javascript 框架(AngularJS)会将函数的返回值注入到构造函数中。

如何从工厂函数外部引用返回的类Record的类型?

/** Define factory to create Record classes */
export default function RecordFactory($window) 
  return class Record  // I want to reference this class as a type
    doSomething() 
      // use $window service
    
  



/**
 * Controller for page with returned class of RecordFactory injected
 * into the constructor
 */
class RecordPageCtrl 
  record
  constructor(Record)  // How do I specify the type of Record here?
    this.record = new Record();
  


// Dependency Injection is handled by AngularJS
angular.module('myApp', [])
  .factory('Record', RecordFactory)
  .controller('RecordPageCtrl', RecordPageCtrl)

注意:我试图避免使用 Record 类上的所有方法维护接口。

【问题讨论】:

【参考方案1】:

这对我有用。

namespace Factored 
  // Class Record wrapped in namespace only to distinguish from other Record usages
  export class Record  // I want to reference this class as a type
    doSomething() 
      // use $window service
    
  ;


/** Define factory to create Record classes */
export default function RecordFactory($window) 
  return Factored.Record; // return class reference


/**
 * Controller for page with returned class of RecordFactory injected
 * into the constructor
 */
class RecordPageCtrl 
  record: Factored.Record;
  constructor(Record: typeof Factored.Record)  // Referencing namespaced class
    this.record = new Record();
    this.record.doSomething();
  


// Dependency Injection is handled by AngularJS
angular.module('myApp', [])
  .factory('Record', RecordFactory)
  .controller('RecordPageCtrl', RecordPageCtrl)

【讨论】:

感谢您的回复。但是,我无法重现这一点。我无法从Record 类访问注入的服务(例如$window)。【参考方案2】:

我重新考虑了如何创建工厂并将服务注入到Record 等类中。通过构造函数传入服务,工厂可以轻松传入服务,让AngularJS处理依赖注入。

/** Class where service needs to be injected */
class Record 
  constructor(private myInjectedService) 
    doSomething() 
      // use myService
      this.myInjectedService.log('Hello World');
    


/** Define factory to create Record class instances */
function RecordFactory(MyService) 
  return new Record(MyService); // return a new class


/**
 * Controller for page 
 * RecordFactory return variable is injected into the constructor
 */
class RecordPageCtrl 
  constructor(public Record: Record) 
    this.Record.doSomething();
  


/** Service to inject into Record class */
class MyService 
    log(message: string) 
        console.log(message);
    


let myServiceInst = new MyService();

// directly instantiated
let factoryInstance = RecordFactory(myServiceInst);
new RecordPageCtrl(factoryInstance);

// Dependency Injection handled by AngularJS
angular.module('myApp', [])
  .factory('Record', RecordFactory)
  .service('MyService', MyService)
  .controller('RecordPageCtrl', RecordPageCtrl)

注意,如果您希望能够在其中注入工厂的位置创建 Record 类的多个实例,则需要让工厂返回另一个工厂,该工厂在调用时实例化该函数。

【讨论】:

以上是关于在工厂函数之外公开本地 TypeScript 类的类型的主要内容,如果未能解决你的问题,请参考以下文章

14-TypeScript简单工厂模式

如何从 TypeScript 函数返回一个类?

如何使用具有构造函数参数的 TypeScript 类定义 AngularJS 工厂

在Typescript中,如何在工厂(ish)函数中实例化的类上获取方法的通用返回类型

15-TypeScript策略模式

TypeScript装饰器