我可以使用自定义模块解析功能(例如" proxyquire")代替带有TypeScript的require()吗?

时间:2016-10-20 16:27:48

标签: node.js typescript proxyquire

我有一个TypeScript文件config.ts,它将与node:

一起运行
import myDependency = require('my-dependency');    

export = {
    doSomething = () => {
        ...
    }
}

在其他TypeScript文件中,我可以import此文件具有完全类型安全性:

import config = require('./config');
config.doSomething();
config.doSomethingElse(); // compiler error, this method doesn't exist

现在我想对这个脚本进行单元测试。为了模拟这个脚本require()使用proxyquire的依赖关系,这让我可以提供我的脚本在调用require()时获得的值。这是我的测试的样子:

import proxyquire = require('proxyquire');
const config = proxyquire('./config', {
    'my-dependency': {} // this mocked object will be provided when config.ts asks for `my-dependency`
});

expect(config.doSomething()).to.do.something();

这项工作正常,但我的config变量的类型为any,因为我使用proxyquire()代替require()。 TypeScript必须为require()函数提供特殊处理,以允许它执行模块解析。有没有办法告诉TypeScript编译器proxyquire()也应该进行模块解析,类似于require()

我可以将config.ts重写为类或使其使用接口。然后我可以通过导入类/接口定义在我的测试中显式地键入变量。但允许proxyquire()为我隐式输入内容将是更容易解决的问题。

1 个答案:

答案 0 :(得分:0)

有一种解决方法 - 您可以通过导入实际模块并在类型转换中使用config.ts来获取typeof模块的类型:

import proxyquire = require('proxyquire');

import configType = require('./config');

const config = <typeof configType> proxyquire('./config', {
    'my-dependency': {} // this mocked object will be provided when config.ts asks for `my-dependency`
});

config.doSomething();

// config.noSuchMethod(); // does not compile

这不是理想的,因为你必须在你的测试中导入相同的模块两次 - 真正的一个只是为了得到它的类型和“proxiquired”一个实际用于你的测试,你必须要小心不将两者混为一谈。但与为typescript实现模块解析的另一种变体的任务相比,它非常简单。此外,当以这种方式使用configType时 - 仅用于键入 - 它的导入甚至不会出现在生成的javacsript代码中。