我可以在函数内部创建一个打字稿类是指它的参数?它的、是指、创建一个、函数

2023-09-14 00:16:08 作者:一击就碎的念头不是梦想

例如。在angularJS我可以用下面的结构:

E.g. in angularJS I may use the following construction:

myApp.factory('MyFactory', function(injectable) {
    return function(param) {
        this.saySomething = function() {
            alert("Param=" + param + " injectable=" +injectable);
        }
    };
});

这可以在以后使用这样的:

This can later be used like this:

function(MyFactory) {
    new MyFactory().saySomething();
}

在传递给方法的功能工厂被调用的参数注射被笼,将进一步提供到无需任何 MyFactory 的新实例重新指定该参数。

When the function passed to the method factory gets invoked, the param injectable is caged and will further be available to new instances of MyFactory without any need to specify that parameter again.

现在我想用打字稿,显然我希望指定我 MyFactory 是可更新,并具有功能 saySomething 。我怎么可以这样优雅的?

Now I want to use TypeScript and obviously I want to specify that my MyFactory is newable, and has a function saySomething. How could I do this elegantly?

我可以这样写:

class MyFactory {
    constructor(private injectable, private param) {}
    saySomething() {
        alert(...);
    }
}
myApp.factory('myFactory', function(injectable) {
    return function(param) {
        return new MyFactory(injectable, param);
    }
});

但是,这改变了API:

But this changes the API:

function(myFactory) {
    myFactory().saySomething();
}

我不知道这可能是更优雅,因为我喜欢怎样的新的前presses很清楚,一个新的唯一对象被创建这个对象的创建是工厂的全部目的。

I wonder if it could be more elegant, because I like how the "new" expresses quite clearly that a new unique object is created and this object creation is the whole purpose of the factory.

推荐答案

我有同样的问题:与AngularJS和ES5,我喜欢依赖注入没有污染的构造,并能够使用关键字。

I have the same problem: with AngularJS and ES5, I enjoy dependency injection not polluting constructors and be able to use the new keyword.

使用ES6你可以用一个类的函数里面,这是尚未得到打字稿(见支持https://github.com/Microsoft/TypeScript/issues/307 )。

With ES6 you can wrap a class inside a function, this is not yet supported by TypeScript (see https://github.com/Microsoft/TypeScript/issues/307).

在这里我做什么(MyFactory现在班级内的TodoItem从待办事项应用程序更相关的):

Here what I do (MyFactory is now class TodoItem from a todo app to be more relevant):

class TodoItem {
  title: string;
  completed: boolean;
  date: Date;

  constructor(private injectable: SomeService) { }

  doSomething() {
    alert(this.injectable);
  }
}

class TodoItemFactory() {
  constructor(private injectable: SomeService) { }

  create(): TodoItem {
    return new TodoItem(this.injectable);
  }

  // JSON from the server
  createFromJson(data: any): TodoItem {
    var todoItem = new TodoItem(this.injectable);
    todoItem.title = data.title;
    todoItem.completed = data.completed;
    todoItem.date = data.date;
    return todoItem;
  }
}

// In ES5: myApp.factory('TodoItem', function(injectable) { ... });
myApp.service('TodoItemFactory', TodoItemFactory);


class TodosCtrl {
  // In ES5: myApp.controller('TodosCtrl', function(TodoItem) { ... });
  constructor(private todoItemFactory: TodoItemFactory) { }

  doSomething() {
    // In ES5: var todoItem1 = new TodoItem();
    var todoItem1 = this.todoItemFactory.create();

    // In ES5: var todoItem2 = TodoItem.createFromJson(...)
    var todoItem2 = this.todoItemFactory.createFromJson(
      {title: "Meet with Alex", completed: false}
    );
  }
}

这是比ES5和功能那么优雅(而不是使用类与打字稿是一个没有去): - /

This is less elegant than with ES5 and functions (and not using classes with TypeScript is a no go) :-/

我想什么,而不是写:

@Factory
@InjectServices(injectable: SomeService, ...)
class TodoItem {
  title: string;
  completed: boolean;
  date: Date;

  // No DI pollution
  constructor() { }

  saySomething() {
    alert(this.injectable);
  }

  static createFromJson(data: string): TodoItem {
    ...
  }
}

@Controller
@InjectFactories(TodoItem: TodoItem, ...)
class TodosCtrl {
  constructor() { }

  doSomething() {
    var todoItem1 = new TodoItem();

    var todoItem2 = TodoItem.createFromJson({title: "Meet with Alex"});
  }
}

或用功能:

myApp.factory(injectable: SomeService) {
  class TodoItem {
    title: string;
    completed: boolean;
    date: Date;

    // No constructor pollution
    constructor() { }

    saySomething() {
      alert(injectable);
    }

    static createFromJson(data: string): TodoItem {
      ...
    }
  }
}

myApp.controller(TodoItem: TodoItem) {
  class TodosCtrl {
    constructor() { }

    doSomething() {
      var todoItem1 = new TodoItem();

      var todoItem2 = TodoItem.createFromJson({title: "Meet with Alex"});
    }
  }
}