'Cannot redeclare block-scoped variable' 在不相关的文件中

'Cannot redeclare block-scoped variable' in unrelated files

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

tsconfig.json:

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

选项-foo.ts:

declare const GlobalVar: any;

function baz() {}

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

选项-bar.ts:

declare const GlobalVar: any;

function baz() {}

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

这里的重要部分是 option-foooption-bar 从未一起使用过。项目中还有其他赠送的TS文件,但不影响,只需要一次编译成JS tsc 运行.

tsc 运行s时,抛出

Cannot redeclare block-scoped variable 'GlobalVar'.

Duplicate function implementation.

Cannot redeclare block-scoped variable 'GlobalVar'.

Duplicate function implementation.

两个文件中的 GlobalVarbaz

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

GlobalVar 并且函数暴露给全局命名空间,TypeScript 警告您变量和方法名称是 re-declared。因为这两个函数是在全局命名空间中声明的,所以只需要声明一次。

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

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

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

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

TL;DR 只需在文件的最外层写入 export {}


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

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

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

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

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

为了解决这个问题,您可以简单地使用一个不导出任何内容的 export 语句。也就是说,只要写

export {};

在你的文件 top-level 的某处。