سلام, محمد گلدست هستم و امروز میخوایم در قسمت دوم از مهاجرت به تایپاسکریپت, در رابطه با تایپ ها صحبت کنیم و دقیقا بررسی کنیم که چرا هنگام بروز اشتباه در توسعه ی نرم افزار, تایپاسکریپت میتونه به ما کمک کنه ولی جاوااسکریپت جلوی مارو برای خطا کردن نمیگیره.
با ساختار تایپ ها در تایپاسکریپت تقریبا آشناییم چون با بعضی از اونها توی جاوااسکریپت زیاد سروکار داریم. بیاین ببینیم از لیست تایپ ها چندتا از اونهارو میشناسیم :
خوب با اینکه از لیست بالا با چندتا از اونها آشنایی داریم ولی میخوایم همه رو توضیح بدیم و بررسی کنیم تا موردی از قلم نیوفته, قبل از بررسی بیاین یاد بگیریم چجور تایپ هارو برای تعریف متغییر استفاده کنیم:
let [VARIABLE_NAME]: [TYPE] = [VALUE];
برای مثال :
let isDone: boolean = false;
خیلی ساده فقط با اضافه کردن نوع متغییر میتونیم برای کامپایلر تایپاسکریپت مشخص کنیم هرجایی که نیاز به استفاده از متغییر isDone بود, شما به من یادآوری کن که از نوع boolean هست, و اجازه نده توی فرایند توسعه, من اشتباه کد بزنم یا چیزی رو اضافه کنم که در هنگام اجرا روی حالت عملیاتی (Production mode) باعث بروز خطا بشه.
نوع Boolean:
ابتدایی ترین داده, مقدار صحیح یا غلط (true | false) است که هم جاوااسکریپت و هم تایپاسکریپت به اون boolean میگن و به شکل زیر قابل تعریف و استفاده است:
let isDone: boolean = false;
نوع Number:
همانند جاوااسکریپت, تمامی اعداد در تایپاسکریپت دارای یک نوع هستند که همه ی این نوع هارو ما Number میشناسیم. علاوه بر hexadecimal و decimal, تایپاسکریپت مقادیر octal و binary رو که در ES2015 معرفی شده بودند رو هم پشتیبانی میکنه. به نمونه های زیر دقت کنید :
let decimal: number = 6; let hex: number = 0xf00d; let binary: number = 0b1010; let octal: number = 0o744;
نوع String:
یکی دیگر از اساسی ترین بخش ها برای ساختن برنامه های جاوااسکریپت, بخش کار با داده های متنی است. مثل تمامی زبان های برنامه نویسی دیگر در تایپاسکریپت به داده های متنی, string میگوییم. دقیقا مانند جاوااسکریپت, تایپاسکریپت هم برای داده های متنی از ( '' ) و ( ' ) استفاده میکند.
هرچند ما برای قالب چند خطی یا قرار دادن متغییر بین داده های متنی دقیقا میتوانیم از ( `` ) همانند جاوااسکریپت استفاده کنیم. به مثال های زیر دقت کنید:
let color: string = "blue" color = 'red'; // backtick/backquote (`) character: let fullName: string = `Bob Bobbington`; let age: number = 37; let sentence: string = `Hello, my name is ${ fullName }. I'll be ${ age + 1 } years old next month.`;
خوب از اونجایی که خودم حوصلهام سر میره همش خشک و خالی فقط بخونم. تصمیم گرفتم یه استراحت بدیم به خودمون و بررسی کنیم چند مثال عملی رو با همین سه نوع بالا که معرفی کردیم.
پس همونجور که توی درس قبل توضیح دادم, یه فایل app.ts درست کردم و شروع کردم به بررسی تفاوتهای تایپاسکریپت و جاوااسکریپت.
عکس زیر رو ببینید:
در مرحله ی اول ما یک کد رو دقیقا بین جاوااسکریپت و تایپاسکریپت مقایسه کردیم. دقت کنید حتی app.ts رو ترنسپایل نکردیم به جاوااسکریپت تا حس دولوپ و اخطار های تایپاسکریپت رو در لحظه تجربه کنیم. و دقت کنید توی قسمت تایپاسکریپت ما هیچ تایپی رو برای متغییر ها معرفی نکردیم.
اینجا اولین چیزی که مشاهده میکنیم, اخطاری هست که تایپاسکریپت به ما میده که آقای برنامه نویس حواست باشه که تایپ های پارامتر ها به دلیل تعریف نشدن, به صورت any در نظر گرفته میشن. یعنی ترنسپایلر تایپاسکریپت میگه بررسی ورودی هارو از عهده ی من خارج کردید و من هرچی اومد رو مستقیم راه میدم بیاد داخل تابع.
حالا اومدیم برای ورودی تابع addInTS یک نوع در نظر گرفتیم و به ترنسپایلر تایپ اسکریپت گفتیم فقط و فقط شما اجازه دارین ورودی از جنس عدد دریافت کنید.
دقت کنید بعد به طور عمدی ما خط ۵ از هر دو فایل رو تبدیل به رشته کردیم ( فرض میکنیم این اشتباه سهوی در حین توسعه به وجود اومده ), به نظر شما چه بازخوردی از این دو زبان میتونیم دریافت کنیم ؟ عکس زیر رو ببینید:
دیدیم که جاوااسکریپت واقعا هیچ ایده ای برای ارسال یک رشته به تابعی که انتظار دریافت عدد رو داره, واسش مطرح نیست و کاملا با خیال راحت اجازه میده شما هر اشتباهی رو عمدا یا سهوا توی کد وارد کنید. ولی اگر دقت کنید تایپاسکریپت به غیرتش برخورده و میگه من حتی اجازه نمیدم که شما بتونید کد رو کامپایل کنید که اگر کامپایل هم کنید این پیام رو دریافت میکنید:
ولی خب شاید شما قبول نکنید و بگید با راه حل زیر میشه حلش کرد موضوع رو:
قبول دارم حرف شمارو, منم نمیگم قطعا راه حلی وجود نداره ولی هدف اینه که هم تمیز تر کد بزنیم هم لذت ببریم و تا جایی که میتونیم از ابزار استفاده کنیم. (شاید نوشتن نرم افزار توی Notepad++ هم ممکن باشه ولی شما هیچوقت نمیتونین سرعت و امکاناتی که VSCode بهتون میده رو با Notepad++ مقایسه کنید).
ما با Object توی جاوااسکریپت آشنایی داریم و میدونیم میشه داده ایی رو به صورت کلید-مقدار رو توسط Object نگهداری کرد. اما بیاین Object زیر رو بدون تعریف نوع در دو زبان برنامه نویسی مقایسه کنیم:
خب بازم تاثیر تایپاسکریپت رو میتونیم حین توسعه ببینیم و متوجه میشیم که توی خط ۹ به ما اخطار میده کلیدی به اسم nickname توی whoAmI تعریف نشده و اعلام میکنه فقط از کلیدهای موجود میتوانید استفاده کنید.
حالا بریم بررسی کنیم چجور میشه برای Objectها نوع تعریف کرد.
خوب میتوینم ببینیم در عکس بالا شیء رو نوع دادیم, و به طور کلی اگر نوع Object رو به شیء بالا نسبت ندیم در بکگراند, ترنسپایلر تایپاسکریپت میاد و تک تک کلید های اون Object رو بررسی میکنه و تایپ رو بهشون نسبت میده, مثل عکس زیر:
دقت کنید به عکس بالا, داره دقیقا یه Object رو به ما میده که شامل کلید-نوع هست و بجای استفاده از (,) بعد از هر کلید-نوع, از (;) استفاده کرده, بچه ها دقت کنید ماهم میتونیم این شیء از نوع هارو برای Objectها بنویسیم و اونهارو خصوصی سازی (Customize) کنیم. به عکس زیر دقت کنید:
توی عکس بالا به دو نکته میتونیم برسیم, یکی اینکه چجور میشه برای کلیدهای یک Object نوع تعریف کرد و اینکه شما وقتی اقدام به تعریف یک نوع برای یک کلید از یک شیء میکنید, ترنسپایلر تایپاسکریپت شمارو موظف میکنه تا همه ی کلیدهارو نوع بدید, همونطور که میبینید هنگام ترنسپایل کردن در ترمینال با پیام خطا مواجه میشیم که برای experience نوع تعریف نکردیم.
بریم عکس زیر رو ببینیم که بحث Object هارو تموم کنیم و بریم سراغ موردهای دیگه:
توی عکس بالا, تایپ هارو مشخص کردیم و میخوایم یک اشتباه عمدا توی کد به وجود بیاریم و ببینیم بازخورد تایپاسکریپت نسبت به اشتباه ما چی هست؟ پس عکس زیر رو ببینید:
اومدیم توی لاین ۱۵, مقدار age رو برابر '23' قرار دادیم و حتی فایل رو ذخیره نکردیم که تایپاسکریپت سریع خودش وارد قضیه شد و اخطار داد که تغییر age به مقدار string ممکن نیست چون قبلا به صورت number تعریف شده است.
یکی از محدودیت های دیگه ی تایپاسکریپت در آرایه ها خودش رو خوب نشون میده به صورتی که در حالت عادی, ما فقط توانایی تعریف آرایه هایی داریم که ایندکس های اون آرایه از یک نوع باشند.
انواع تعریف آرایه:
آرایه هارو به دو روش میشه طراحی کرد, در روش اول با نوشتن نوع و سپس نماد [] میتوان اشاره کرد که این متغییر از نوع آرایه است یا میتوان از روش <Array<INDEX_TYPE استفاده کرد به مثال زیر دقت کنید:
let strings: string[] = ['Hello'، 'World'، '!'];
let numbers: Array<number> = [1، 2، 3، 4، 5];
آرایههای دو بُعدی:
let numbersArray: number[][] = [[1،2،3،4،5]، [6،7،8،9،10]];
خوب دوست دارین بررسی کنیم ببینیم تعریف نوع آرایه برای یک متغییر چقدر میتونه بهمون کمک کنه حین کد نویسی ؟ پس با هم میتونیم جاوااسکریپت و تایپاسکریپت رو توی عکس زیر بررسی کنیم:
در عکس بالا مشاهده میکنیم وقتی یک مقدار به hobbies در شیء تعریف شده ی بالاتر اضافه میکنیم اگر مقداری باشه که مورد انتظار تایپاسکریپت نباشه, سریعا مانع میشه و اخطار میده ولی جاوااسکریپت به شما اصلا اخطار نمیده هرچند این کد در جاوااسکریپت دچار خطا نمیشه چون آرایه ها در جاوااسکریپت به صورت any تعریف میشن و هر مقداری رو توی خودشون ذخیره میکنند.
عکس زیر رو ببینید تا یکی دیگر از کمک های تایپاسکریپت رو باهم دیگه بررسی کنیم:
لاین ۱۷ و ۱۸ و ۱۹ رو باهم یه بررسی کنیم. ببینید توی عکس بالا اومدیم آرایه ی hobbies رو پیمایش کردیم و عمدا نوشتیم item.map(). این مورد از نظر دو زبان بازخوردهای متفاوتی رو به همراه داشت, دقت کنید تایپ اسکریپت اطلاع داره که hobbies, خونه هایی از نوع رشته رو داراست ولی جاوااسکریپت هیچ ایدهایی راجب اینکه قراره چه رفتاری رو خونه های hobbies بگیرند, نداره.
این مورد اگه در جاوااسکریپت بره روی سرور و اجرا بشه, بعد از اجرا دچار خطا میشه ولی در تایپاسکریپت وقتی که هنوز کد شما ذخیره هم نشده, خطای خودش رو نشون میده و به شما میگه که سریعا اصلاح کنید. بیاین خطای کامپایل کد بالارو هم بررسی کنیم توی تایپاسکریپت:
امیدوارم تونسته باشم کل تجربیات خودم از یادگیری رو تا اینجا برای شما به اشتراک گذاشته باشم.
به زودی در قسمت بعد, سایر تایپها رو بررسی میکنیم و بیشتر مثال های عملی میزنیم. ?
محمد گلدست / دوازدهم فروردین ماه ۱۳۹۹.