在node.js中有一种众所周知的方法来利用模块工厂模式。,例如:
m.js
function factoryMethod(module) {
// doing some stuff and returning object initialized with module parameter
}
app.js
var o = require('./m')(module);
// using o
如何在打字稿中做同样的事情?实际上,创建m.ts不是问题:
m.ts
function factoryMethod(module: NodeModule): any {
// doing some stuff
}
export = factoryMethod;
但是我应该如何使用导入语法来使用这个模块工厂方法像在javascript?
我不确定我是否完全理解这种常见模式。你把module
对象从一个模块传递到另一个模块?所有其他类型的对象都是这样传递的(例如app
, db
),但我不喜欢传递module
对象的想法。我很想称它为反模式。当然,module
对象应该留在它所属的模块中。
require()
函数来实现这一点,就像普通的JavaScript一样。让我们假设您正在通过快速app
而不是module
。
const o = require('./m')(app);
但是,这样做会失去类型安全性;o
的类型为any
。您必须显式地定义o
的类型。
const o: Module = require('./m')(app);
这有点傻。事实上,Module
很可能是在您需要的模块中定义的,所以它也可能会弄巧成拙。我的建议是。不要期望在TypeScript中使用你在纯JS中使用的模式,因为TypeScript有自己的模式。
您可以做的一件事是在顶部导入函数,然后稍后调用它。TypeScript使用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;
}
接口允许在app.ts
中进行类型推断,这是一种改进。
// app.ts
import {factoryMethod} from './m';
// ...
let o = factoryMethod(app);
但这仍然很愚蠢。我们不需要定义接口和所有那些无意义的东西。相反,我们可以使用类。在TypeScript中,类通常是答案,你会发现TypeScript中的大多数模式都涉及到类。
// m.ts
export class Module {
constructor(private app: Express.Application) { }
cache: string[];
someMethod(): Promise<Express.Response> {
// do something with this.app
}
}
在app.ts
import {Module} from './m';
// ...
let o = new Module(app);
现在我们不用担心接口之类的了。类本身是一种类型。这与你在典型的Node应用中可能看到的有很大的不同,但它是你在TypeScript中经常看到的那种模式。
希望这能给你一些启发
import {factoryMethod} from './m.ts'
let module = factpryMethod('module');
我知道这个问题相当老了,但我在将现有的JS项目转换为使用这种模式的TypeScript时遇到了同样的问题。
不必在接口中预先定义模块定义,我们可以使用ReturnType
帮助器来获得函数返回类型的类型定义!
模块可能是这样的:
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>;
我们可以这样使用它:
import initModule, { SampleModule } from './factory';
const newModule: SampleModule = initModule(1, 2);
newModule.functionA(); // 1
newModule.functionB(); // 2
说真的,TypeScript有多酷?:)