به طور کلی سطوح مختلفی از scope وجود دارد که تعیین می‌کند که کد ما به چه متغیرهایی می‌تواند دسترسی داشته باشد یا این که متغیرهای جدید چگونه باید سایر بخش‌های کد تعامل برقرار نمایند. در این مقاله قصد داریم تا تعریف مجدد یک متغیری که دارای block scope است را باهم بررسی کنیم.

خطایی که ممکن است هنگام کار کردن با متغیرها با آن مواجه شویم Cannot redeclare block-scoped variable 'name'. است. این خطا احتمالاً به این دلیل رخ می‌دهد که ما دو متغیر با نام یکسان داریم، یا این که ممکن است سعی کرده باشیم چیزی را در scope سراسری تغییر دهیم. بر اساس نوع مشکلی که داریم چند راه حل وجود دارد که در ادامه آن‌ها را بررسی می‌کنیم.

راه حل اول: تغییر نام متغیر

اگر دو متغیر با نام یکسان در یک scope داشته باشیم، با خطای زیر مواجه می‌شویم:

let id = 123;
Cannot redeclare block-scoped variable 'id'.

let id = 456;
Cannot redeclare block-scoped variable 'id'.

این خطا به این دلیل است که وقتی یک متغیر تعریف می‌شود، مقدار آن در حافظه ذخیره می‌گردد. اگر بخواهیم متغیر دیگری را با همان نام در همان scope تعریف کنیم، سعی می‌کند متغیر جدید را نیز در همان مکان ذخیره کند که این کار باعث ایجاد خطا می‌شود.

بنابراین، ساده‌ترین راه حل تغییر نام یکی از متغیرها است.

راه حل دوم: تغییر scope متغیر

اگر قصد داریم نام متغیرها را حفظ کنیم، می‌توانیم scope یکی از متغیرها را تغییر دهیم:

let id = 123;

{
  let id = 456;

  console.log(id); // 456
}

console.log(id); // 123

این روش به این دلیل کار می‌کند که دو متغیر در scopeهای مختلف قرار دارند. متغیر id اول در module scope و id دوم در block scope است. اما همانطور که می‌بینیم، این کار می‌تواند برای افرادی که کد ما را می‌خوانند گیج‌کننده باشد. ما باید از نام‌گذاری مشابه متغیرها در scopeهای مختلف اجتناب نماییم.

راه حل سوم: ماژول ما یک ماژول نیست!

اگر دو متغیر با نام یکسان نداریم، ممکن است به طور تصادفی سعی کرده باشیم که scope سراسری را تغییر دهیم. به عنوان مثال ممکن است خطای زیر را داشته باشیم:

Cannot redeclare block-scoped variable 'name'.
const name = "Matt";

ما فقط یک name در فایل خود داریم، پس چرا باید با این خطا مواجه شویم؟

این خطا به دو دلیل اتفاق می‌افتد. اول اینکه فایل ما هیچ import یا exportای در خود ندارد. اگر یک export خالی اضافه کنیم، خطا برطرف می‌شود:

const name = "Matt";

export {};

هنگامی که تایپ اسکریپت هیچ import یا exportای را نمی‌بیند، فایل را یک اسکریپت می‌داند نه یک ماژول. اسکریپت‌ها از طریق تگ <script /> در scope سراسری مرورگرها بارگذاری می‌شوند. بنابراین، هر کدی که در اینجا می‌نویسیم در همان scope سراسری مانند window و document است.

همانطور که مشخص است، name یکی از این متغیرهای سراسری می‌باشد. بنابراین، زمانی که می‌خواهیم متغیری را با همین نام تعریف کنیم، تایپ اسکریپت خطا می‌دهد.

تنظیم moduleDetection بر روی force

اگر بر روی پروژه‌ای کار می‌کنیم که هر فایل یک ماژول است، نه یک اسکریپت، باید مقدار moduleDetection در فایل tsconfig.json خود به force تغییر دهیم. این کار باعث می‌شود تا تایپ اسکریپت با هر فایلی به‌عنوان یک ماژول رفتار کند، حتی اگر import یا exportای وجود نداشته باشد.

{
  "compilerOptions": {
    "moduleDetection": "force"
  }
}

‌.درنهایت، راه حل سوم بهترین راه حل برای جلوگیری از به وجود آمدن این خطا به حساب می‌آید