فایل tsconfig: گزینه‌های noEmitOnError و strict و noImplicitAny

noEmitOnError, strict and noImplicitAny

10 مرداد 1399

گزینه noEmitOnError

در ادامه بحث جلسات قبل در این قسمت نیز قرار است گزینه های بیشتری از فایل tsconfig را مورد بررسی قرار دهیم. isolatedModule گزینه بعدی ما است اما ما نیازی به آن نداریم بنابراین از آن رد می شویم. یکی دیگر از گزینه هایی که اصلا در فایل tsconfig.json وجود ندارد noEmitOnError است. این گزینه به صورت پیش فرض داخل فایل tsconfig قرار ندارد اما کاملا معتبر است و شما می توانید از آن استفاده کنید. حالت پیش فرض این گزینه false است. برای نمایش کارایی این گزینه بهتر است به صورت عملی کار کنیم. حتما کد زیر را از جلسات قبل به یاد دارید:

const button = document.querySelector('button')!;

button.addEventListener('click', () => {
    console.log('clicked!');
});

فرض کنید علامت ! را از انتهای خط اول حذف کنم تا به خطا برخورد کنیم. در حال حاضر اگر بخواهیم این کد را کامپایل کنیم، خطای زیر را در ترمینال مشاهده می کنیم:

خطای نمایش داده شده در ترمینال
خطای نمایش داده شده در ترمینال

اما با این حال هنوز هم فایل جاوا اسکریپت ما کامپایل می شود. بله، برخی اوقات خطایی در فایل های تایپ اسکریپت است که به دلیل سخت گیری زبان تایپ اسکریپت می باشد و واقعا مشکلی برای برنامه ما ندارند (به طور مثال همین کد بالا) اما در بسیاری از اوقات اینطور نیست و خطاهای تایپ اسکریپت واقعا به خطا در زمان run-time تبدیل می شوند.  اینجاست که بهتر است noEmitOnError را روی true قرار دهید تا در صورتی که خطایی در یکی از فایل های ما وجود داشت، فایل ها کامپایل نشوند:

"noEmitOnError": true

توجه داشته باشید که در این حالت اگر حتی یکی از فایل های ما خطا داشته باشد، هیچ خروجی نخواهیم داشت، حتی برای فایل های دیگر. به طور مثال در کد بالا که در فایل app.ts می باشد، خطا داریم. حالا اگر tsc را اجرا کنیم حتی خروجی analytics.ts را نیز نمی بینیم بنابراین هیچ فایل جاوا اسکریپتی کامپایل نمی شود. بهتر است همیشه این گزینه را فعال بگذارید و گرنه هدف از تولید فایل های جاوا اسکریپت خطا دار چیست؟

تا این قسمت تمام گزینه هایی که داشتیم، مربوط به تنظیمات ساده بود و با کامنت زیر مشخص شده بود:

/* Basic Options */

حالا باید به تنظیمات قسمت بعد برویم که مربوط به تنظیمات strict است و با کامنت زیر در فایل tsconfig.json مشخص شده است:

/* Strict Type-Checking Options */

اولین گزینه در این قسمت گزینه strict است که در حالت پیش فرض فعال است:

"strict": true

این گزینه تمام type-checking (بررسی تایپ ها) ها را به صورت strict (به معنی «سخت گیرانه») انجام می دهد. فعال بودن strict به معنای فعال بودن تمام گزینه های بعد از آن در این قسمت است:

    /* Strict Type-Checking Options */
    "strict": true,                           
    "noImplicitAny": false,                 
    "strictNullChecks": true,              
    "strictPropertyInitialization": true,  
    "noImplicitThis": true,                
    "alwaysStrict": true,

در حالت پیش فرض تمام گزینه های بالا بعد از strict غیرفعال هستند و strict فعال می باشد و همانطور که گفتم فعال بودن strict یعنی فعال بودن تمام گزینه های بعدی. بنابراین دو راه دارید: یا strict را فعال کنید تا همه گزینه های بعد از آن در قسمت strict فعال شوند و یا اینکه strict را کامنت کرده و فقط بعضی از گزینه های بعد از آن را فعال کنید. بگذارید آن ها را تک به تک توضیح بدهم.

اولین گزینه، noImplicitAny است که به ما کمک می کند کدهای بهتری بنویسیم. فرض کنید کد زیر را درون فایل analytics.ts داشته باشیم:

function sendAnalytics(data) {
  console.log(data);
}

sendAnalytics('The data');

ویرایشگر ما به ما خطا خواهد داد که نوعی برای data (پارامتر تابع) تعریف نشده است بنابراین به صورت پیش فرض و غیرمستقیم تایپ any را گرفته است. noImplicitAny (که در واقع no implicit any – به معنی «بدون any های غیر مستقیم» است) به تایپ اسکریپت می گوید اگر جایی تایپ any وجود داشت و کاربر شخصا آن را تعریف نکرده بود (implicit و غیر مستقیم توسط خود تایپ اسکریپت حدس زده شده باشد) گزارش خطا بده و به اینطور any ها اجازه نوشته شدن نده. اگر من noImplicitAny را غیرفعال کنم خطای ما هم برطرف می شود:

    "strict": true,                           
    "noImplicitAny": false

کد بالا می گوید تمام قوانین strict فعال باشند به جز noImplicitAny. البته پیشنهاد می شود هیچ وقت چنین کاری نکنید و همیشه قوانین این قسمت را true قرار دهید تا کدهای بهتری بنویسید. بنابراین بهتر است به جای خاموش کردن خطا، مشکل را با مشخص کردن تایپ پارامتر حل کنید:

function sendAnalytics(data: string) {
  console.log(data);
}

البته جالب است که کد زیر خطا نمی گیرد:

let logged;

function sendAnalytics(data: string) {
  console.log(data);
  logged = true;
}

با اینکه خط اول متغیری به نام logged داریم که به صورت غیرمستقیم تایپ any می گیرد اما خطایی نمی گیریم. دلیلش چیست؟ تایپ اسکریپت نمی تواند تشخیص دهد که پارامتر ورودی درون تابع در انتهای کد چه چیزی را می گیرد اما می تواند متغیرها را ردیابی کند. به طور مثال اگر کد بالا را به شکل زیر تغییر دهیم متوجه خواهیم شد:

let logged;

function sendAnalytics(data: string) {
  console.log(data);
  logged = true;
  console.log(logged);
}

تایپ اسکریپت بعد از قسمتی که logged را روی true گذاشته ایم متوجه می شود که تایپِ متغیرِ logged از نوع Boolean است:

تشخیص نوع متغیر پس از انتساب داده
تشخیص نوع متغیر پس از انتساب داده

بنابراین نیازی به خطا نیست اما نمی تواند چنین کاری را با پارامتر های ورودی تابع انجام دهد. البته همیشه پیشنهاد می شود که برای متغیر هایی مانند logged نیز تایپ تعریف کنید تا بعدا دچار مشکل نشوید.

بقیه گزینه های بخش strict را به همراه گزینه های باقی مانده در قسمت بعد مشخص خواهیم کرد.

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری آموزش جامع تایپ اسکریپت توصیه می‌کند:
نویسنده شوید

دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

ما را دنبال کنید
اینستاگرام روکسو تلگرام روکسو ایمیل و خبرنامه روکسو