web-dev-qa-db-ja.com

関連のないファイルでは「ブロックスコープ変数を再宣言できません」

CommonJSモジュールとして使用され、エクスポートのないシンプルなTSパッケージがあります。 TSファイルは、同じ名前のJSファイルにコンパイルされ、require('package/option-foo')として使用されます。

tsconfig.json:

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

option-foo.ts:

declare const GlobalVar: any;

function baz() {}

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

option-bar.ts:

declare const GlobalVar: any;

function baz() {}

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

ここで重要なのは、option-foooption-bar一緒に使用されることはないであることです。プロジェクトには他の無料のTSファイルがありますが、それらは何にも影響を与えず、1回のtsc実行でJSに変換する必要があります。

tscが実行されると、スローされます

ブロックスコープの変数 'GlobalVar'を再宣言できません。

関数の実装が重複しています。

ブロックスコープの変数 'GlobalVar'を再宣言できません。

関数の実装が重複しています。

両方のファイルのGlobalVarおよびbazに対して。

ビルドプロセスまたはこれら2つのTSファイルからの出力を複雑にすることなく、これをどのように処理できますか?

50
Estus Flask

TL; DRファイルの最も外側のスコープにexport {}と書くだけです。


ある時点で、ファイルをmodule(および独自のスコープを持つ)として扱うかscript(および他のスクリプトとグローバルスコープを共有します)。

ブラウザでは、これは簡単です-<script type="module">タグを使用でき、モジュールを使用できるようになります。

しかし、JavaScriptを利用する他の場所はどうでしょうか?残念ながら、現時点ではその区別をするための標準的な方法はありません。

TypeScriptが問題に取り組むことを決定した方法は、単にモジュールがインポートまたはエクスポートを含む任意のファイルであると述べることでした。

そのため、ファイルにトップレベルのimportまたはexportステートメントが含まれていない場合、グローバル宣言が相互に干渉する問題が発生することがあります。

これを回避するには、何もエクスポートしないexportステートメントを簡単に作成します。言い換えれば、ただ書く

export {};

ファイルの最上位のどこかに。

119

GlobalVarと関数はグローバル名前空間に公開され、TypeScriptは変数とメソッド名が再宣言されることを警告しています。 2つの関数はグローバル名前空間で宣言されているため、一度だけ宣言する必要があります。

これを行うには、名前空間を使用します。

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

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

名前空間名bar.bazまたはfoo.bazを使用して、C#で呼び出すのと同じ方法で関数を呼び出すことができます。

18
freedeveloper