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

Mic*_*Mic 5 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 '$'.
Run Code Online (Sandbox Code Playgroud)

问题是两个包都声明了一个全局$变量.您也可以在"全局值"下的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/**/*"
    ]
}
Run Code Online (Sandbox Code Playgroud)

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

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

Mic*_*Mic 0

已经很久了,但我找到了解决方案!

\n\n

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

\n\n

tsconfig.project.json

\n\n
{\n    "compilerOptions": {\n        "target": "ES6",\n        "module": "commonjs",\n        "sourceMap": false,\n        "inlineSourceMap": true,\n        "inlineSources": true,\n        "watch": false,\n        "declaration": false,\n        "outDir": "dist",\n        "typeRoots": ["./typings"],\n    },\n    "include": [\n        "src/**/*"\n    ],\n    "exclude": [\n        "src/test/*"\n    ]\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

tsconfig.test.json

\n\n
{\n    "compilerOptions": {\n        "target": "ES6",\n        "module": "commonjs",\n        "sourceMap": false,\n        "inlineSourceMap": true,\n        "inlineSources": true,\n        "watch": false,\n        "declaration": false,\n        "outDir": "dist",\n        "typeRoots": ["./typings"],\n    },\n    "include": [\n        "src/test/*"\n    ]\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
{\n...\n  "scripts": {\n    "test": "tsc -p tsconfig.test.json && mocha --exit dist/test",\n    "tsc": "tsc -p tsconfig.project.json",\n    ...\n  },\n...\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
"types": []\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
\n

@types、typeRoots 和类型

\n\n

默认情况下,所有可见的 \xe2\x80\x9c@types\xe2\x80\x9d 包都包含在\n 编译中。任何封闭文件夹的 node_modules/@types 中的包\n 都被视为可见;具体来说,这意味着 \n ./node_modules/@types/、../node_modules/@types/、\n ../../node_modules/@types/ 等中的包。

\n\n

如果指定了 typeRoots,则仅包含 typeRoots 下的包。\n

\n\n

...

\n\n

指定 "types": [] 以禁用自动包含\n @types 包。

\n\n

请记住,仅当您使用具有全局声明的文件(而不是声明为模块的文件)时,自动包含才重要。例如,如果您使用 import "foo" 语句,\n TypeScript 仍可能会查找 node_modules 和 node_modules/@types\n 文件夹来查找 foo 包。

\n
\n\n

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

\n