阻止d.ts模块提供默认导出

时间:2019-06-28 08:20:17

标签: typescript

我分发了一个Node.js模块,其类型附加为d.ts文件。该模块没有公开默认的导出,但是由于某种原因,Typescript允许从该模块执行默认的导入,并且该默认的导入错误地公开了所有命名的导出,这允许错误地使用该模块并导致运行时崩溃。

module.js

'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

exports.foo = function foo () {
  console.log("foo")
}

module.d.ts

export declare function foo ()

tsconfig.json

{
    "compilerOptions": {
        "target": "esnext",
        "moduleResolution": "node",
        "experimentalDecorators": true,
        "allowJs": true,
        "esModuleInterop": true,
        "noEmit": true
    }
}

测试案例1

import { foo } from "./module"

foo()

按预期工作,打印“ foo”。

测试案例2

import module from "./module"

module.bar()

按预期方式工作,无法编译:

/Users/semenov/xxx/node_modules/ts-node/src/index.ts:261
    return new TSError(diagnosticText, diagnosticCodes)
           ^
TSError: ⨯ Unable to compile TypeScript:
test.ts(3,8): error TS2339: Property 'bar' does not exist on type 'typeof import("/Users/semenov/xxx/module")'.

测试案例3

import module from "./module"

module.foo()

没有像我期望的那样给出Typescript编译错误。相反,它在运行时崩溃:

/Users/semenov/xxx/test.ts:3
module.foo()
       ^
TypeError: Cannot read property 'foo' of undefined
    at Object.<anonymous> (/Users/semenov/xxx/test.ts:3:8)
    at Module._compile (internal/modules/cjs/loader.js:701:30)
    at Module.m._compile (/Users/semenov/xxx/node_modules/ts-node/src/index.ts:439:23)
    at Module._extensions..js (internal/modules/cjs/loader.js:712:10)
    at Object.require.extensions.(anonymous function) [as .ts] (/Users/semenov/xxx/node_modules/ts-node/src/index.ts:442:12)
    at Module.load (internal/modules/cjs/loader.js:600:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:539:12)
    at Function.Module._load (internal/modules/cjs/loader.js:531:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:754:12)
    at Object.<anonymous> (/Users/semenov/xxx/node_modules/ts-node/src/bin.ts:157:12)

问题

如何在d.ts文件中指定模块不提供默认导出(并为测试用例3给出编译错误)?还是将默认导出类型设置为nevervoid或类似的名称,以便至少不允许使用module.foo

我知道我可以在项目中禁用esModuleInterop,但是它将停止导入大多数其他cjs程序包,包括那些没有类型的程序(例如,import path from "path"将不会编译)。

0 个答案:

没有答案