jquery TypeScriptの変数定義時のコンパイルエラー :ブロック スコープの変数 ‘name’ を再宣言することはできません。ts(2451)

2023年2月8日

TypeScript で name などの特定の識別子を使って変数を定義するとコンパイルエラーが発生します(ファイルがモジュールでない場合)。

index.ts

const name: string = 'foo';
console.log(name);
% npx tsc   //コンパイルを実行        
src/index.ts:1:7 - error TS2451: Cannot redeclare block-scoped variable 'name'.

1 const name: string = 'foo';
        ~~~~
  node_modules/typescript/lib/lib.dom.d.ts:17878:15
    17878 declare const name: void;
                        ~~~~
    'name' was also declared here.

Found 1 error in src/index.ts:1

以下は VS Code でのスクリーンショットですが、name という名前の変数を宣言した時点で以下のエラーが発生します。

ブロック スコープの変数 'name' を再宣言することはできません。ts(2451)
lib.dom.d.ts(17878, 15): ここでは 'name' も宣言されました。

コンパイルを実行すると、以下のようなコンパイルエラーになります。

error TS2451: Cannot redeclare block-scoped variable 'name'.

エラーになる理由

TypeScript をインストールすると、JavaScript や DOM の型定義が付属していて、その中の DOM API の型定義ファイル(lib.dom.d.ts)に、name がすでに定義されているために発生します(同じ変数を再宣言できない)。

関連ページ:TypeScript 環境の構築(lib.d.ts)

そのため、name の他にも TypeScript をインストールした際に付属される型定義ファイルで宣言されている変数名と同じもの(length、locationなど)は同様のエラーになります。

エラーが出ないようにするには以下のような方法があります。

  • 変数名を name 以外に変更する
  • export {}; を追加する
  • ブロック内に記述する

解決方法1

変数名を name 以外に変更します(付属の型定義ファイルで定義されていない識別子に変更します)。

const uname: string = 'foo';  //name 以外に変更

console.log(uname);

解決方法2

ファイルがスクリプトとして扱われる場合、トップレベルに定義した変数のスコープはファイル内だけではなくプロジェクト全体になるため、このエラーが発生します。

モジュールとして扱われる場合はモジュール内で定義された変数のスコープはそのモジュール内になります。

TypeScript の場合、コード中に import や export が使われている場合は自動的にモジュールとして扱われるので、export {}; を追加することでそのファイルをモジュールとすることができます。

以下のように空の変数をエクスポートする export {}; を追加して、ファイルをモジュールとします。

const name: string = 'foo';

console.log(name);

export {}; //追加

解決方法3

グローバル変数にならないようにブロック化します。但し、変数のスコープはブロック内に限定されます。

{
  const name: string = 'foo';

  console.log(name);
}