有一个简单的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-foo
和option-bar
从未一起使用。项目中还有其他免费的TS文件,但它们不会影响任何内容,只需要在tsc
次运行中转换为JS。
当tsc
运行时,它会抛出
无法重新声明块范围变量'GlobalVar'。
重复的功能实现。
无法重新声明块范围变量'GlobalVar'。
重复的功能实现。
,两个文件中的GlobalVar
和baz
。
如果不使构建过程或这两个TS文件的输出复杂化,如何处理它?</ p>
答案 0 :(得分:116)
TL; DR 只需在文件的最外层写入export {}
。
在某些时候,需要对文件是否应被视为模块(并具有自己的范围)或脚本(和共享)进行语义歧义消除其他脚本的全局范围。)
在浏览器中,这很简单 - 您应该能够使用<script type="module">
标记,并且您将能够使用模块。
但是其他任何使用JavaScript的地方呢?不幸的是,目前还没有一种标准方法可以做出这种区分。
TypeScript决定解决问题的方法是简单地声明模块包含导入或导出的任何文件。
因此,如果您的文件没有任何类型的顶级import
或export
语句,那么您偶尔会看到全局声明相互干扰的问题。< / p>
为了解决这个问题,您可以简单地使用export
语句来导出任何内容。换句话说,只需写
export {};
位于文件顶层的某处。
答案 1 :(得分:17)
GlobalVar
并且函数暴露给全局命名空间,TypeScript警告您重新声明变量和方法名称。因为这两个函数是在全局命名空间中声明的,所以你只需要声明它们一次。
如果要执行此操作,请使用名称空间。
namespace foo {
declare const GlobalVar: any;
function baz() {}
}
namespace bar {
declare const GlobalVar: any;
function baz() {}
}
您可以使用命名空间名称bar.baz
或foo.baz
来调用函数,方法与在C#中调用它们的方式相同。