安装多个 typescript 类型定义,声明相同的全局变量
Posted
技术标签:
【中文标题】安装多个 typescript 类型定义,声明相同的全局变量【英文标题】:Install multiple typescript type definitions declaring the same global variable 【发布时间】:2018-08-19 17:31:53 【问题描述】:我正在使用 typescript、node 和 electron 构建一个应用程序。
我在应用程序中使用 jquery,并且我已经安装了 @types/jquery 包以获得智能提示。
接下来我使用 mocha 和 spectron 创建了一个测试。 Spectron 使用 webdriverio 并通过一些属性公开其 API。我需要使用这些属性,所以我安装了@types/webdriverio 以获得智能提示。
现在,每当我运行 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/@types 中的所有源代码一起编译。事实上,如果我删除 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编写的代码示例,它们一起使用:这在打字稿中不可行吗?
【问题讨论】:
【参考方案1】:好久不见,终于找到解决办法了!
您需要定义两个单独的 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 配置,它覆盖了 typescript 编译器的默认行为。默认行为是加载在任何 @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 包。
请记住,自动收录仅在您满足以下条件时才重要 使用具有全局声明的文件(与声明为的文件相反 模块)。 例如,如果您使用 import "foo" 语句, TypeScript 可能仍会查看 node_modules 和 node_modules/@types 文件夹来查找 foo 包。
另一个重要的一点是分离配置文件。这样,您可以在编译主项目时排除测试文件,反之亦然。这很重要,因为主项目包含 jquery,而测试文件包含 webdriverio。将它们一起编译,您会得到问题中描述的相同错误。
【讨论】:
以上是关于安装多个 typescript 类型定义,声明相同的全局变量的主要内容,如果未能解决你的问题,请参考以下文章
【笔记】使用Vite搭建Vue3(TypeScript版本)项目