Visual Studio 2017中的TypeScript:自动定义包含会导致重复标识符错误

Bri*_*Rak 26 typescript typescript-typings visual-studio-2017

更新:我有一个解决方法,使事情工作可以接受,没有黑客.我将下面描述的先前尝试留给子孙后代.请参阅工作解决方案的答案.


我刚刚将一个项目升级到Visual Studio 2017,我突然得到了各种类型的TypeScript错误.其中许多都是Duplicate identifier错误的.当我双击其中一个错误时,它会打开一个名为index.d.ts的文件,该文件位于以下目录中:

C:\Users\[me]\AppData\Local\Microsoft\TypeScript\node_modules\@types\jquery\index.d.ts
Run Code Online (Sandbox Code Playgroud)

根据我在此页面上阅读的内容:

https://blogs.msdn.microsoft.com/visualstudio/2016/11/28/more-productive-javascript-in-visual-studio-2017-rc/

...似乎正在发生的事情是Visual Studio正在尝试帮助下载我已经手动包含定义文件的类型的定义文件.自动包含定义文件听起来像一个很棒的功能!我只是删除手动包含的,对吧?但我所做的一切似乎都无效.我希望有人可以告诉我哪里出错了.

对于背景,我在Visual Studio 2015中工作的方式如下.我正在使用三个库:jQuery,jQuery UI和QUnit.我只是从DefinitelyTyped下载了.d.ts文件并将它们放在我的项目中的Scripts目录中,一切正常,直到我在VS 2017中打开项目.

从错误消息来看,似乎Visual Studio 2017引入了自己的定义文件,所以我想我只是删除我手动带来的那些文件.但是,当我这样做时,现在我遇到了大量Cannot find name $错误,这似乎意味着这些定义文件不再由于某种原因而被引入.

接下来,我想可能问题是我的项目中实际上没有JQuery(和其他库)源文件.我只是在我的HTML源代码中从Google的CDN引用它们.上面的链接听起来像Visual Studio正在寻找一个实际的松散文件作为它应该带入定义文件的指示器.所以我手动将文件添加到我的Scripts目录并重建,但没有任何改变.

上面的链接页面还讨论了从npm或bower包含你的库文件,或者使用tsconfig.json文件,但是在我走这些道路之前(不是我正常工作流程的一部分),我希望有人可以告诉我,是有一种在Visual Studio 2017中引入TypeScript定义的首选方法吗?提前致谢.


更新:(见下面的更新2)我能够让事情发生.这不完全是直观的,所以我在这里分享我的步骤,希望a)它可以帮助某人,b)有人可以告诉我,如果我只是以错误的方式做这件事.

  1. 从项目中删除所有TypeScript代码和定义文件.
  2. 打开packages.json并删除任何定义文件引用.
  3. 清洁和建造.没有错误或警告.
  4. 通过NuGet,安装您需要的定义文件(例如,对于jQuery,您想要的包是"jquery.TypeScript.DefinitelyTyped").
  5. 这将在Scripts\typings\jquery中安装定义文件.
  6. 对您引用的其他库执行相同操作.
  7. 添加新的测试TypeScript文件并添加尝试使用库的行,例如, var foo = $(document);
  8. 智能感知工作!项目建设!看起来我们又回来了!
  9. 没那么快.几秒钟后,我们再次收到重复标识符错误.似乎Visual Studio自己选择了定义文件(可能是通过我通过NuGet包含定义文件激活的),现在我们再次发生冲突.
  10. 使用以下指令添加tsconfig.js文件,这会阻止Visual Studio下载自己的定义文件副本: { "compilerOptions": { "types": [] } }
  11. 错误消失了.
  12. 没那么快!几秒钟后,出现了数百个新错误,引用了我已从项目中完全删除的TypeScript文件.打开错误窗口中引用的其中一个文件,看起来是复制品<Project>\obj\Debug\...(路径较长但我忘记记录)
  13. 没有多少清洁解决方案摆脱这些文件.
  14. obj手动删除整个目录.
  15. 将我原来的所有TypeScript文件添加回项目中.
  16. 重建.成功!

更新2:我发现上述方法存在一些缺点.我也有更好的解决方案.

使用tsconfig.json有一个主要的缺点.在保存时重新编译的选项在Visual Studio中不起作用.我希望我的网站在调试模式下运行,对TypeScript进行一些更改,点击保存,然后立即看到网站中反映的那些更改.

我认为给我带来麻烦的一件事就是我将TypeScript文件放在Scripts以外的文件夹中,我保留了应该按原样部署到服务器的文件.我想微软认为这是一个非标准的用例.

在我的头撞到墙上太长时间之后,我找到了一个简单的,虽然很笨拙的解决方案.我把这个目录中的所有子目录:

C:\Users\[me]\AppData\Local\Microsoft\TypeScript\node_modules\@types
Run Code Online (Sandbox Code Playgroud)

并将它们移动到名为Deleted的目录.

巴姆.不再自动包含定义,不再有错误.

微软,如果您正在阅读,请为我的方案提供支持,重申的是:

  • 存储在脚本以外的目录中的TypeScript文件
  • 通过引用第三方CDN包含库(例如jQuery)
  • 上述库的定义文件直接通过NuGet包含.

更新3:我终于开始工作了.请参阅下面的答案,了解非hacky解决方案.

Bri*_*Rak 17

我得到它没有黑客的工作.诀窍是使用tsconfig.json文件并禁用自动定义包含.在我原来的问题中,我提到我试过这个,发现我无法使用compile-on-save.但是,那是因为我试图使用"watch"选项,当我真的应该使用"compileOnSave"选项时.

这是我完整的工作步骤,将我原来的,破碎的项目转换为可正常工作的项目,并将继续在Visual Studio 2017的未经修改的安装上正常工作.

tsconfig.json在根目录下向项目添加文件.

至少配置您的文件:

{ "compilerOptions": { "types": [] } }
Run Code Online (Sandbox Code Playgroud)

但也许你喜欢其他选择.我的文件看起来像这样:

{
  "compileOnSave": true,
  "compilerOptions": {
    "types": [],
    "sourceMap": true,
    "target": "es5",
    "noEmitOnError": true
  }
}
Run Code Online (Sandbox Code Playgroud)

您可以在此处了解其他编译器选项:https: //www.typescriptlang.org/docs/handbook/compiler-options.html

这"types":[]是阻止自动包含定义的部分.

这意味着您可以为您使用的任何库引入定义.幸运的是,通过NuGet非常容易.例如,对于jQuery,只需搜索jquery.TypeScript.DefinitelyTyped并安装适当的版本.这将创建下的文件夹Scripts/typings.

如果您以前遇到过错误,可能需要清除一些错误.清理项目,删除obj项目目录结构顶部的目录,现在应该正确构建.当我在文件中键入内容然后再次保存时,我遇到了一些杂散错误.重新启动Visual Studio也可能正常.

祝好运!


更新:我发现当我发布到Azure时,我又遇到了错误.但是,当我将下面的Perfa建议的指令添加到我的tsconfig.json文件中时,删除了我的bin和obj目录并重新启动了Visual Studio,这些错误也不再出现.我现在已经多次构建,重建并发布到Azure,它们似乎已经完全消失了.

为清楚起见,我的完整tsconfig.json文件现在看起来像这样:

{
  "compileOnSave": true,
  "compilerOptions": {
    "types": [],
    "sourceMap": true,
    "target": "es5",
    "noEmitOnError": true
  },
  "exclude": [
    "node_modules",
    "obj",
    "bin"
  ]
}
Run Code Online (Sandbox Code Playgroud)


小智 6

安装VS 2017后我遇到了这个错误.为了摆脱它,我用obj和bin更新了我的tsconfig.json exclude部分.

"exclude": [
    "node_modules",
    "obj",
    "bin"
  ]
Run Code Online (Sandbox Code Playgroud)