0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【TypeScript】'Cannot redeclare block-scoped variable' 独自のスコープを持つファイルかグローバルスコープを持つファイルか?

Last updated at Posted at 2022-07-23

TypeScriptの勉強中にあるエラーに遭遇した。

Cannot redeclare block-scoped variable 'users'

「usersの変数は既に宣言されているので再宣言できないよ」というエラーらしい。

今回は以下のような場合で発生した。

src/chapter-3/index.ts
const users = [];
src/capter-4/index.ts
const users = [{ name: 'jhon', age: 27 }];

※ちなみにディレクトリ構成はこんな感じ

.
├── README.md
├── dist
├── node_modules
├── package-lock.json
├── package.json
├── src
│   ├── chapter-3
│   │   └── index.ts
│   └── chapter-4
│       └── index.ts
└── tsconfig.json

あれ、同じファイル内でこのエラーが発生するならわかるんだけど、ディレクトリを跨いでいるファイルでもこのエラーは発生するのか。。

調べてみると・・・

まずこのエラーはEslintのno-redeclareが発しているエラーで、同じスコープ内で複数の宣言を持つ変数を排除することを目的としているエラー。

TypeScriptで新しいファイルを作成すると以下の2つに分類されるらしい。
・ファイルが独自のスコープを持つモジュールとして宣言されている。
・ファイルがグローバルスコープを共有するスクリプトとして宣言されている。

今回の場合は後者に分類されるため、users変数のスコープがグローバルとなっていて、ディレクトリを跨いでも同様の変数名で宣言した場合にエラーが発生したようだった。

なるほど。なのであればそれぞれのファイルを独自のスコープを持つモジュールとして宣言させる必要がある。
以下のようにexport {};をファイル内に記載するとファイルがモジュールとして認識されるみたい。
※今回はどちらかのファイルに記載すればエラー自体は解決するけどすべてのファイルをモジュールにしておきたいので両方に記載した。

src/chapter3/index.ts
export {};
const users = [];
src/capter4/index.ts
export {};
const users = [{ name: 'jhon', age: 27 }];

TypeScriptで新しいファイルを宣言した際に、以下のどちらかに分類されることは学びでした。
ファイルが独自のスコープを持つモジュールとして宣言されている
ファイルがグローバルスコープを共有するスクリプトとして宣言されている

◆あとがき
でもexport{}をすべてのファイルに書くのは面倒すぎる。。 今回は勉強用のファイルなので良いが実際のプロジェクトとなるとこれはよろしくない。
tsconfigの設定とかでどうにかできるものなのかなぁ。
あとフレームワークとかでプロジェクトを作成した際は、あんまり意識しないからその辺はフレームワークがうまく調整してくれているのかなぁと思っている。

コメントなどでなんでも教えていただけるととても喜びます!!!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?