简体   繁体   English

打字稿模块工厂模式

[英]Typescript module factory pattern

There is a well-known approach in node.js to leverage the module factory pattern. node.js 中有一种众所周知的方法来利用模块工厂模式。 For, example:例如:

m.js js

function factoryMethod(module) {
  // doing some stuff and returning object initialized with module parameter
}

app.js应用程序.js

var o = require('./m')(module);
// using o

How can I do the same in typescript.我如何在打字稿中做同样的事情。 Actually, creating m.ts is not a problem:其实创建m.ts不是问题:

m.ts m.ts

function factoryMethod(module: NodeModule): any {
  // doing some stuff
}

export = factoryMethod;

But how should I use import syntax to use this module factory method like in javascript?但是我应该如何使用导入语法来像在 javascript 中一样使用这个模块工厂方法?

import {factoryMethod} from './m.ts'


let module = factpryMethod('module');

I'm not sure I quite get this common pattern. 我不确定我是否会得到这种通用模式。 You're passing the module object from one module into another? 您要将module对象从一个模块传递到另一个模块? All kinds of other objects are passed around like this, (eg app , db ), but I don't like the idea of passing around the module object. 各种各样的其他对象都是这样传递的(例如appdb ),但是我不喜欢传递module对象的想法。 I'd be tempted to call it an anti-pattern. 我很想称其为反模式。 Surely the module object should stay in the module to which it belongs. 当然, module对象应该留在它所属的模块中。

That said, if you just want to import and call a function on the same line, you could do this using Node's require() function, just like regular JavaScript. 就是说,如果您只想在同一行上导入并调用一个函数,则可以使用Node的require()函数完成此操作,就像常规JavaScript一样。 Let's say you are passing an Express app rather than module . 假设您要传递Express app而不是module

const o = require('./m')(app);

However, you lose type-safety with this; 但是,您将因此失去类型安全性。 o will be of type any . o将为any类型。 You would have to explicitly define the type of o . 您将必须明确定义o的类型。

const o: Module = require('./m')(app);

This is a bit silly. 这有点傻。 In fact, Module is likely to be defined in the module you are requiring anyway, so it is likely also self-defeating. 事实上, Module可能是你需要反正模块中进行定义,所以它也有可能弄巧成拙。 My suggestion is this. 我的建议是这个。 Don't expect to use the same patterns you are used to in plain JS in TypeScript, which has its own patterns. 不要期望使用与TypeScript中的普通JS相同的模式,后者具有自己的模式。

One thing you could do is import the function at the top, and then call it later. 您可以做的一件事是在顶部导入该函数,然后再调用它。 TypeScript uses ES2015-style modules , which don't allow you to import a function and call it on the same line. TypeScript使用ES2015样式的模块 ,这些模块不允许您导入函数并在同一行上调用它。 You will have to rewrite both files, since export = is not valid in ES2015. 您将必须重写两个文件,因为export =在ES2015中无效。

// m.ts

interface Module {
  // properties, methods, etc.
}

export function factoryMethod(app: Express.Application): Module {
  let module = {};
  // Initialize module methods, properties, etc.
  return module;
}

The interface allow type inference in app.ts , which is an improvement of a kind. 接口允许在app.ts进行类型推断,这是一种改进。

// app.ts

import {factoryMethod} from './m';

// ...

let o = factoryMethod(app);

But this is still very silly. 但这仍然很愚蠢。 We don't need to define an interface and all that nonsense. 我们不需要定义接口和所有的废话。 Instead, we can use a class . 相反,我们可以使用class Classes are very often the answer in TypeScript, and you'll find that most patterns in TypeScript involve them. 在TypeScript中,类通常是答案,并且您会发现TypeScript中的大多数模式都涉及到它们。

// m.ts

export class Module {

  constructor(private app: Express.Application) { }

  cache: string[];

  someMethod(): Promise<Express.Response> {
    // do something with this.app
  }

}

And then in app.ts 然后在app.ts

import {Module} from './m';

// ...

let o = new Module(app);

Now we don't have to worry about interfaces and all that. 现在,我们不必担心接口等所有问题。 The class itself is a type. 类本身是一种类型。 This is quite a bit different from what you are likely to see in a typical Node app, but it is the sort of pattern you find all the time in TypeScript. 这与典型的Node应用程序中可能会看到的内容有很大不同,但这是您一直在TypeScript中发现的那种模式。

Hopefully that gives you some ideas. 希望能给你一些想法。

I know this question is fairly old but I came across the same issue when converting an existing JS project to TypeScript that makes use of this pattern.我知道这个问题已经很老了,但是在将现有的 JS 项目转换为使用这种模式的 TypeScript 时,我遇到了同样的问题。

Instead of having to pre-define the module definition in an interface we can use the ReturnType helper to get a type definition of the return type of a function!不必在接口中预先定义模块定义,我们可以使用ReturnType助手来获取函数返回类型的类型定义!

This is what the module might look like:这是模块可能的样子:

function initModule(arg1: number, arg2: number) {
  function functionA() {
    return arg1;
  }
  function functionB() {
    return arg2;
  }

  return {
    functionA,
    functionB,
  };
}

export default initModule;

export type SampleModule = ReturnType<typeof initFactory>;

And here is how we could use it:这是我们如何使用它:

import initModule, { SampleModule } from './factory';

const newModule: SampleModule = initModule(1, 2);

newModule.functionA(); // 1
newModule.functionB(); // 2

Seriously, how cool is TypeScript?说真的,TypeScript 有多酷? :) :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 TypeScript工厂模式表示属性不存在 - TypeScript factory pattern says property doesnt exist 相当于JS模块模式的打字稿 - Typescript equivalent to JS Module pattern typescript-以类型表示模块模式 - typescript - representing module pattern in types 如何在 Typescript 中为现有的 JavaScript 模块模式编写模块模式 - How to write the Module Pattern in Typescript for an existing JavaScript Module Pattern TypeScript代码类似于Revealing Module Pattern结构 - TypeScript code similar to Revealing Module Pattern structure 为什么TypeScript混合模块和原型模式? - Why does TypeScript mix the module and prototype pattern? 在模块模式中使用工厂 function 声明 object 时,我无法访问模块内的数组 - When declaring an object using a factory function in a module pattern, I am unable to access an array inside the module typescript / JS模块模式。 分割成多个文件 - typescript/JS module pattern. splitting into multiple files TypeScript:使用动态导入的工厂模式不允许构造该对象的新实例以进行合成 - TypeScript: Factory pattern to use dynamic imports is not allowing to construct new instance of the object for composition 客户端 typescript:如何从工厂方法模式中删除循环依赖? - Client-side typescript: how do I remove circular dependencies from the factory method pattern?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM