typescript 不相关文件中的“无法重新声明块范围变量”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/40900791/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 07:30:03  来源:igfitidea点击:

'Cannot redeclare block-scoped variable' in unrelated files

typescripttsc

提问by Estus Flask

There is a simple TS package that is used as CommonJS modules and has no exports. TS files are compiled to JS files with the same name and used as require('package/option-foo').

有一个简单的 TS 包用作 CommonJS 模块并且没有导出。TS 文件被编译为同名的 JS 文件并用作require('package/option-foo').

tsconfig.json:

tsconfig.json:

{
  "compilerOptions": {
    "target": "es5"
  }
}

option-foo.ts:

选项-foot.ts:

declare const GlobalVar: any;

function baz() {}

if (GlobalVar.foo) GlobalVar.baz = baz;

option-bar.ts:

选项bar.ts:

declare const GlobalVar: any;

function baz() {}

if (GlobalVar.bar) GlobalVar.baz = baz;

The important part here is that option-fooand option-barare never used together. There are other complimentary TS files in the project, but they don't affect anything, just needed to be transpiled to JS in one tscrun.

这里最重要的部分是option-foooption-bar从来没有一起使用。项目中还有其他免费的 TS 文件,但它们不影响任何东西,只需tsc运行一次即可转译为 JS 。

When tscruns, it throws

tsc运行时,它抛出

Cannot redeclare block-scoped variable 'GlobalVar'.

Duplicate function implementation.

Cannot redeclare block-scoped variable 'GlobalVar'.

Duplicate function implementation.

无法重新声明块范围变量“GlobalVar”。

重复的函数实现。

无法重新声明块范围变量“GlobalVar”。

重复的函数实现。

for GlobalVarand bazin both files.

forGlobalVarbaz在这两个文件中。

How can this be treated without complicating build process or the output from these two TS files?

如何在不使构建过程或这两个 TS 文件的输出复杂化的情况下处理这种情况?

回答by Daniel Rosenwasser

TL;DRJust write export {}in the outermost scope of your files.

TL;DR只需export {}在文件的最外层范围内写入即可。



At some point there needs to be a semantic disambiguation for whether a file should be treated as a module(and have its own scope) or a script(and share the global scope with other scripts).

在某些时候,需要对文件应该被视为模块(并具有自己的范围)还是脚本(并与其他脚本共享全局范围)进行语义消歧。

In the browser, this is easy - you should be able to use a <script type="module">tag and you'll be able to use modules.

在浏览器中,这很容易——您应该能够使用<script type="module">标签并且您将能够使用模块。

But what about any other place that utilizes JavaScript? Unfortunately there isn't a standard way at this point to make that distinction.

但是其他任何使用 JavaScript 的地方呢?不幸的是,目前还没有标准的方法来区分。

The way that TypeScript decided to tackle the problem was to simply state that a module is any file which contains an import or export.

TypeScript 决定解决这个问题的方法是简单地声明一个模块是任何包含 import 或 export 的文件

So if your file doesn't have any sort of top-level importor exportstatements, then you'll occasionally see issues with global declarations interfering with each other.

因此,如果您的文件没有任何类型的顶级importexport语句,那么您偶尔会看到全局声明相互干扰的问题。

To get around this, you can simple have an exportstatement that exports nothing. In other words, just write

为了解决这个问题,您可以简单地创建一个export不导出任何内容的语句。换句话说,只要写

export {};

somewhere at the top-level of your file.

位于文件顶层的某个位置。

回答by freedeveloper

GlobalVarand the functions are exposed to the global namespace, and TypeScript is warning you that the variable and the method name are re-declared. Because the two function are declared in the global namespace, you only need to declare them one time.

GlobalVar并且函数公开给全局命名空间,TypeScript 警告您重新声明变量和方法名称。因为这两个函数都是在全局命名空间中声明的,所以只需要声明一次即可。

If you want to do this, use namespaces.

如果要这样做,请使用命名空间。

namespace foo {    
    declare const GlobalVar: any;
    function baz() {}
}

namespace bar {
    declare const GlobalVar: any;
    function baz() {}
}

You can call the functions in the same way as you call them in C#, by using the namespace name: bar.bazor foo.baz.

您可以使用与在 C# 中调用函数相同的方式调用这些函数,方法是使用命名空间名称:bar.bazfoo.baz.