【问题标题】:Can I use a custom module resolution function (like "proxyquire") in place of require() with TypeScript?我可以在 TypeScript 中使用自定义模块解析函数(如“proxyquire”)代替 require() 吗?
【发布时间】:2017-03-02 18:26:24
【问题描述】:

我有一个 TypeScript 文件 config.ts 将与节点一起运行:

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()s 的依赖关系,我正在使用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() 为我隐式输入内容将是更简单的解决方案。

【问题讨论】:

    标签: node.js typescript proxyquire


    【解决方案1】:

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

    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”一个以便在您的测试中实际使用,您必须小心不要把两者混为一谈。但与为打字稿实现另一种模块解析变体的任务相比,它非常简单。此外,当 configType 以这种方式使用时 - 仅用于输入 - 它的导入甚至不会出现在生成的 javacsript 代码中。

    【讨论】:

      猜你喜欢
      • 2019-01-29
      • 2018-10-26
      • 2020-05-13
      • 2021-11-05
      • 2021-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多