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一样的模块工厂方法?
答案 0 :(得分:1)
import {factoryMethod} from './m.ts'
let module = factpryMethod('module');
答案 1 :(得分:1)
我不确定我是否会得到这种常见模式。您是否将module
对象从一个模块传递到另一个模块?所有类型的其他对象都是这样传递的(例如app
,db
),但我不喜欢传递module
对象的想法。我很想把它称为反模式。当然module
对象应该保留在它所属的模块中。
也就是说,如果您只想在同一行导入并调用函数,可以使用Node require()
函数执行此操作,就像常规JavaScript一样。我们假设您传递的是快递app
而不是module
。
const o = require('./m')(app);
然而,你失去了类型安全性; o
的类型为any
。您必须明确定义o
的类型。
const o: Module = require('./m')(app);
这有点傻。实际上,Module
可能会在您要求的模块中定义,因此它可能也会弄巧成拙。我的建议是这样的。不要期望在TypeScript中使用与普通JS相同的模式,它有自己的模式。
您可以做的一件事是在顶部导入函数,然后再调用它。 TypeScript使用ES2015-style modules,它不允许您导入函数并在同一行上调用它。您必须重写这两个文件,因为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中一直找到的那种模式。
希望能给你一些想法。