安装多个打字稿类型定义,声明相同的全局变量

时间:2018-03-11 17:02:12

标签: jquery node.js typescript webdriver-io

我正在使用打字稿,节点和电子构建应用程序。

我在应用程序中使用了jquery,并且我安装了@ types / jquery包以获得intellisense提示。

接下来,我使用mocha和spectron创建了一个测试。 Spectron使用webdriverio并通过一些属性公开其API。我需要使用这些属性,所以我安装了@ types / webdriverio以获得intellisense提示。

现在,每当我运行tsc工具来编译项目时,我都会遇到以下错误:

node_modules/@types/jquery/index.d.ts(36,15): error TS2451: Cannot redeclare block-scoped variable '$'.
node_modules/@types/webdriverio/index.d.ts(1898,18): error TS2451: Cannot redeclare block-scoped variable '$'.
node_modules/@types/webdriverio/index.d.ts(1899,18): error TS2451: Cannot redeclare block-scoped variable '$'.

问题是这两个包都声明了一个全局$变量。您也可以在“全局值”下的npm页面中验证它:

https://www.npmjs.com/package/@types/jquery

https://www.npmjs.com/package/@types/webdriverio

我不明白为什么tsc试图将它们一起编译,因为我没有在同一个.ts文件中使用jquery和webdriverio?

另外,即使我注释掉测试,所以我在任何地方都没有引用webdriverio,当我运行tsc时,我得到了同样的错误。可能tsc正在编译node_modules / @类型中的所有源。实际上,如果我删除了node_modules / @ types / webdriverio文件夹并再次运行tsc,我就不会收到错误(当然,只要我保持测试代码的注释)。

这是我的tsconfig.json,它位于项目的根目录中:

{
    "compilerOptions": {
        "target": "ES6",
        "module": "commonjs",
        "sourceMap": false,
        "inlineSourceMap": true,
        "inlineSources": true,
        "declaration": false,
        "outDir": "dist"
    },
    "include": [
        "src/**/*"
    ]
}

我的所有源代码都在src目录中。测试在src / test。

我是否有任何配置可以保持webdriverio和jquery类型在编译时分开?另外,我已经看到一些用js编写的代码示例,它们一起使用:这在typescript中是不可行的吗?

1 个答案:

答案 0 :(得分:0)

已经很长时间了,但是我找到了解决方案!

您需要定义两个单独的tsconfig:一个用于主项目,一个用于测试。

tsconfig.project.json

{
    "compilerOptions": {
        "target": "ES6",
        "module": "commonjs",
        "sourceMap": false,
        "inlineSourceMap": true,
        "inlineSources": true,
        "watch": false,
        "declaration": false,
        "outDir": "dist",
        "typeRoots": ["./typings"],
    },
    "include": [
        "src/**/*"
    ],
    "exclude": [
        "src/test/*"
    ]
}

tsconfig.test.json

{
    "compilerOptions": {
        "target": "ES6",
        "module": "commonjs",
        "sourceMap": false,
        "inlineSourceMap": true,
        "inlineSources": true,
        "watch": false,
        "declaration": false,
        "outDir": "dist",
        "typeRoots": ["./typings"],
    },
    "include": [
        "src/test/*"
    ]
}

然后,在package.json文件中定义两个不同的脚本,以针对刚刚定义的两个tsconfig运行tsc:

{
...
  "scripts": {
    "test": "tsc -p tsconfig.test.json && mocha --exit dist/test",
    "tsc": "tsc -p tsconfig.project.json",
    ...
  },
...
}

关键是typeRoots配置,它将覆盖打字稿编译器的默认行为。默认行为是加载在任何@types文件夹下定义的每个软件包(因此,包括在node_modules文件夹中安装的每个@types)。 通过覆盖此配置,仅在引用时在node_modules中包含@types。或者,您可以将typeRoots配置替换为

"types": []

来自https://www.typescriptlang.org/docs/handbook/tsconfig-json.html

  

@ types,typeRoots和类型

     

默认情况下,所有可见的“ @types”软件包均包含在您的   编译。任何封闭文件夹的node_modules / @ types中的软件包   被认为是可见的;具体来说,这意味着   ./node_modules/@types/,../node_modules/@types/,   ../../node_modules/@types/,依此类推。

     

如果指定了typeRoots,则只有typeRoots下的软件包是   包括在内。

     

...

     

指定“类型”:[]禁止自动包含   @types软件包。

     

请记住,只有当您   使用带有全局声明的文件(与声明为   模块)。 例如,如果您使用导入的“ foo”语句,   TypeScript可能仍然会浏览node_modules和node_modules / @ types   文件夹中找到foo软件包。

另一个重要的一点是分离配置文件。这样,您可以在编译主项目时排除测试文件,反之亦然。这很重要,因为主项目包括jquery,而测试文件包括webdriverio。一起编译它们,您将得到问题中描述的相同错误。