کار خود با TypeScript را در سال ۲۰۱۹ شروع کنید - بخش دوم

گردآوری و تالیف : عرفان کاکایی
تاریخ انتشار : 21 اردیبهشت 1398
دسته بندی ها : جاوا اسکریپت

طبق بررسی توسعه دهندگان Stack Overflow در سال ۲۰۱۸، TypeScript به عنوان یک زبان برنامه نویسی، نسبت به JavaScript بیشتر دوست داشته شده است. علت این که TypeScript اینقدر میان توسعه دهندگان JavaScript محبوب است، این است که اضافه کردن typeها به JavaScript شما را قادر می‌سازد تا قبل از اجرای کد خود، خطاهای آن را بیابید. خطاهای فراهم شده توسط کمپایلر JavaScript، نحوه برطرف شدن یک خطا را به خوبی نشان خواهند داد. اضافه کردن typeها به JavaScript همچنین ویرایشگرهای کد را قادر می‌سازد تا برخی امکانات پیشرفته‌تر، مانند تکمیل کد، بازسازی در حد پروژه و وارد کردن خودکار ماژول را فراهم کنند.

در بخش دوم این مقاله با ما همراه باشید...

typeهای استاتیک پایه

خب، بیایید به سینتکس TypeScript وارد شویم. در ادامه، رایج‌ترین typeها در TypeScript را مشاهده می‌نمایید.

نکته: من typeهای _never_ و _object_ را جا انداخته‌ام؛ زیرا در تجربه من این typeها خیلی مورد استفاده قرار نمی‌گیرند.

Boolean

مقادیر true و false ساده که آن‌ها را می‌شناسید و دوست دارید.

let isAwesome: boolean = true;

رشته (string)

داده متنی که در single quote، double quote یا back tickها محاصره شده است.

let name: string = 'Chris';

let breed: string = 'Border Collie';

اگر از back tickها استفاده کنید، رشته مورد نظر یک قالب ادبی نام دارد و عبارات می‌توانند داخل آن‌ها تفسیر شوند.

let punchline: string = 'Because it was free-range.';

let joke: string = `

    Q: Why did the chiken cross the road?

    A: ${punchline}

`;

عدد (number)

به هر عدد دارای اعشار، type عدد داده می‌شود. چهار نوع عدد که به عنوان بخشی از TypeScript پشتیبانی می‌شوند، decimal، binary، octal و hexadecimal هستند.

let decimalNumber: number = 42;

let binaryNumber: number = 0b101010; // => 42

let octalNumber: number = 0o52; // => 42

let hexadecimalNumber: number = 0x2a; // => 42

نکته: شما تنها کسانی نیستید که توسط typeهای decimal، binary، octal و hexadecimal گیج می‌شوید.

آرایه

Typeهای آرایه در TypeScript می‌توانند به دو روش نوشته شوند. اولین روش، نیاز دارد که [ ] به عنوان type عناصری که در آرایه یافت می‌شوند، تعیین شود.

let myPetFamily: string[] = ['rocket', 'fluffly', 'harry'];

راه دیگر برای نوشتن typeهای آرایه، این است که از Array به همراه type عناصری که در آرایه یافت شده‌اند، استفاده کنید.

let myPetFamily: Array<string> = ['rocket', 'fluffly', 'harry'];

tuple

یک tuple، آرایه‌ای است که شامل یک تعداد ثابت از عناصر، به همراه typeها می‌باشد.

let myFavoriteTuple: [string, number, boolean];

myFavoriteTuple = ['chair', 20, true]; // ✅
myFavoriteTuple = [5, 20, true]; // ❌ - اولین عنصر باید یک رشته باشد، نه یک عدد

enum

یک enum، راهی است برای این که نام‌ها را به یک مقدار ثابت پیوند دهید، و این مقدار ثابت می‌تواند یک عدد یا یک رشته باشد. Enumها وقتی می‌خواهید مجموعه‌ای از مقادیر متمایز را داشته باشید که یک نام توصیف کننده به همراه خود دارند، کاربردی هستند.

به طور پیشفرض، enumها به اعداد اختصاص داده می‌شوند که از صفر شروع می‌شوند و به ازای هر عضو enum مورد نظر، به مقدار ۱ عدد افزایش می‌یابند.

enum Sizes {
    Small,
    Medium,
    Large,
}


Sizes.Small; // => 0
Sizes.Medium; // => 1
Sizes.Large; // => 2

اولین مقدار می‌تواند برابر با مقداری غیر از صفر قرار داده شود.

enum Sizes {

    Small = 1,

    Medium,

    Large,

}



Sizes.Small; // => 1

Sizes.Medium; // => 2

Sizes.Large; // => 3

Enumها به طور پیشفرض به اعداد اختصاص داده می‌شوند. گرچه، مقادیر رشته هم می‌توانند به یک enum اختصاص داده شوند.

enum ThemeColors {

    Primary = 'primary',

    Secondary = 'secondary',

    Dark = 'dark',

    DarkSecondary = 'darkSecondary',

}

any

اگر type یک متغیر ناشناخته باشد و ما نخواهیم که type checker ما در هنگام کمپایل کردن شکایتی داشته باشد، می‌توان از any استفاده کرد.

let whoKnows: any = 4; // یک عدد اختصاص داده شده است

whoKnows = 'a beautiful string'; // می‌تواند مجددا به یک رشته اختصاص داده شود
whoKnows = false; // می‌تواند مجددا به یک بولین اختصاص داده شود

any ‌به احتمال زیاد وقتی که TypeScript را آغاز می‌کنید، مکررا استفاده خواهد شد. گرچه بهتر است که مقدار استفاده از any را کاهش دهید؛ زیرا وقتی که کمپایلر از type موجود به همراه متغیرها آگاه نیست، کاربردی بودن TypeScript کاهش می‌یابد.

void

وقتی که هیچ typeای به چیزی اختصاص داده نشده است، void باید مورد استفاده قرار گیرد. این مورد بیشتر در هنگام مشخص کردن مقادیر برگشتی یک تابع که چیزی را بر نمی‌گرداند، استفاده می‌شود.

const darkestPlaceOnEarth = (): void => {
    console.log('Marianas Trench');
};

null و undefined

هم null و هم undefined مطابق type مقادیر null و undefined هستند که شاید در JavaScript ببینید. این typeها وقتی که به تنهایی استفاده می‌شوند، خیلی کاربردی نیستند.

let anUndefinedVariable: undefined = undefined;
let aNullVariable: null = null;

typeهای null و undefined به طور پیشفرض، subtype (زیر نوع) تمام typeهای دیگر هستند، که یعنی یک مقدار null یا undefined، می‌تواند به یک متغیر با نوع string اختصاص داده شود. این اغلب یک رفتار مطلوب است و از این رو پیشنهاد می‌شود گزینه کمپایلر strictNullChecks را در فایل tsconfig.json برابر با true قرار دهید. برابر قرار دادن strictNullChecks برابر با true، باعث می‌شود واجب باشد که null و undefined به صراحت به عنوان type یک متغیر تنظیم شوند.

Type Inference (اشاره به type)

خوشبختانه نیازی نیست که در همه جای کد خود typeها را به طور مطلق مشخص کنید؛ زیرا TypeScript چیزی به نام Type Inference دارد. Type Inference چیزی است که کمپایلر TypeScript از آن استفاده می‌کند تا به طور خودکار typeها را تعیین کند.

Type Inference پایه

TypeScript می‌تواند در حین راه‌اندازی متغیر، وقتی که مقادیر پارامتر پیشفرض تنظیم شده‌اند و وقتی که در حال تعیین مقادیر برگشتی تابع هستید، به typeها اشاره کند.

// راه‌اندازی متغیر

let x = 10; // x is given the number type

در مثال بالا، یک عدد به x اختصاص داده شده می‌باشد، و TypeScript یک type عددی را به متغیر x اختصاص داده است.

// پارامترهای پیشفرض تابع

const tweetLength = (message = 'A default tweet') => {

    return message.length;

};

در مثال بالا، یک مقدار پیشفرض به پارامتر message که نوع string را دارد، اختصاص داده شده است؛ پس از این رو کمپایر TypeScript اشاره می‌کند که message در واقع type رشته را دارد و از این رو وقتی که به ویژگی length دسترسی یافت می‌شود، هیچ خطای کمپایلی نشان داده نمی‌شود.

function add(a: number, b: number) {
    return a + b;
}

const result = add(2, 4);

result.toFixed(2); // ✅
result.length; // ❌ - طول، ویژگی نوع‌های عددی نیست

در مثال بالا، از آنجایی که به TypeScript گفته شده است که هر دو پارامتر تابع add، از نوع عددی هستند، TypeScript می‌تواند اشاره کند که type مربوطه به زودی یک عدد خواهد بود.

اشاره Best Common Type

وقتی که از چند type به یک type اشاره می‌شود، TypeScript از یک الگوریتم به نام «Best Common Type» استفاده می‌کند، تا یک type را انتخاب کند که با تمام نامزدهای دیگر هم کار کند.

let list = [10, 22, 4, null, 5];

list.push(6); // ✅
list.push(null); // ✅
list.push('nope'); // ❌ - type 'string' is neither of type 'number' or 'null'

در مثال بال، آرایه مورد نظر از typeهای number و null تشکیل شده است، و از این رو TypeScript فقط مقادیر number و null را به عنوان بخشی از آرایه انتظار دارد.

نشانه‌گذاری type

وقتی که سیستم Type Inference کافی نیست، نیاز خواهد بود که typeها را بر روی متغیرها و آبجکت‌ها تعریف کنید.

typeهای پایه

تمام typeهایی که در بخش typeهای استاتیک پایه معرفی شدند، می‌توانند با استفاده از یک «:» به همراه نام type مورد نظر تعریف شوند.

let aBoolean: boolean = true;
let aNumber: number = 10;
let aString: string = 'woohoo';

آرایه‌ها

همانطور که در بخش مربوطه به type آرایه نمایش داده شد، آرایه‌ها می‌توانند به دو روش نشانه‌گذاری شوند.

// اولین متد در حال استفاده از نشانه‌گذاری براکت است
let messageArray: string[] = ['hello', 'my name is fred', 'bye'];

// دومین متد از نشانه‌گذاری کلمه کلیدی آرایه استفاده می‌کند
let messageArray: Array<string> = ['hello', 'my name is fred', 'bye'];

رابط‌ها

یک راه برای این که چند نشانه‌گذاری typeها در کنار هم قرار دهید، استفاده از رابط آن‌ها است.

interface Animal {

    kind: string;

    weight: number;

}



let dog: Animal;


dog = {
    kind: 'mammal',
    weight: 10,
}; // ✅



dog = {
    kind: true,
    weight: 10,
}; // ❌ - kind should be a string

نام مستعار type

برای این که همه چیز گیج‌کننده شود، TypeScript همچنین شما را قادر می‌سازد تا چند نشانه‌گذاری type را با استفاده از یک نام مستعار، مشخص کنید.

type Animal = {

    kind: string;

    weight: number;

};



let dog: Animal;



dog = {

    kind: 'mammal',

    weight: 10,

}; // ✅



dog = {

    kind: true,

    weight: 10,

}; // ❌ - kind should be a string

چیزی که به نظر می‌رسد بهترین روش در زمینه استفاده از یک رابط یا نام مستعار type می‌باشد، این است که معمولا فقط یا interface یا type را در سورس کد خود انتخاب کنید. گرچه، اگر در حال نوشتن یک API عمومی هستید که می‌تواند توسط دیگران استفاده شود، از نوع interface استفاده کنید.

نشانه‌گذاری خطی

به جای ساخت یک رابط با قابلیت استفاده مجدد، شاید نشانه‌گذاری یک type به صورت خطی مناسب‌تر باشد.

let dog: {

    kind: string;

    weight: number;

};



dog = {

    kind: 'mammal',

    weight: 10,

}; // ✅



dog = {

    kind: true,

    weight: 10,

}; // ❌ - kind should be a string

عمومی

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

const fillArray = <T>(len: number, elem: T) => {

    return new Array<T>(len).fill(elem);

};

const newArray = fillArray<string>(3, 'hi'); // => ['hi', 'hi', 'hi']

newArray.push('bye'); // ✅
newArray.push(true); // ❌ - فقط رشته‌ها می‌توانند به آرایه اضافه شوند

مثال بالا یک type عمومی به نام T دارد که مطابق type آرگومان دوم منتقل شده به تابع fillArray می‌باشد. دومین آرگومان منتقل شده به تابع fillArray، یک رشته است و از این رو آرایه ساخته شده تمام عناصر خود را برابر با type رشته خواهد داشت.

بهتر است دقت کنید که عبارات تک حرفی (مانند T یا K)، طبق قرارداد برای typeهای عمومی استفاده می‌شوند. گرچه، هیچ چیز جلوی شما را نمی‌گیرد تا از نام‌های توصیفی در typeهای عمومی خود استفاده کنید. در اینجا مثالی را که با یک نام توصیفی برای type عمومی عرضه شده است، مشاهده می‌نمایید:

const fillArray = <ArrayElementType>(len: number, elem: ArrayElementType) => {

    return new Array<ArrayElementType>(len).fill(elem);

};


const newArray = fillArray<string>(3, 'hi'); // => ['hi', 'hi', 'hi']

newArray.push('bye'); // ✅
newArray.push(true); // ❌ - فقط رشته‌ها می‌توانند به آرایه اضافه شوند

Type متحد

در سناریوهایی که یک type می‌تواند یکی از چندین type موجود باشد، با جداسازی گزینه‌های type مختلف با استفاده از یک |، یک type متحد مورد استفاده قرار می‌گیرد.

// The `name` parameter can be either a string or null

const sayHappyBirthdayOnFacebook = (name: string | null) => {

    if (name === null) {

        console.log('Happy birthday!');

    } else {

        console.log(`Happy birthday ${name}!`);

    }

};


sayHappyBirthdayOnFacebook(null); // => "Happy birthday!"
sayHappyBirthdayOnFacebook('Jeremy'); // => "Happy birthday Jeremy!"

Type متقاطع

یک type متقاطع، از علامت & برای ترکیب چند type با یکدیگر استفاده می‌کند. این مورد با type متحد تفاوت دارد؛ زیرا یک type متحد می‌گوید: «type نهایی، یکی از چند type لیست شده است»، درحالیکه type متقاطع می‌گوید: «type نهایی، ترکیبی از تمام typeهای لیست شده است»

type Student = {

    id: string;

    age: number;

};

type Employee = {

    companyId: string;

};

let person: Student & Employee;

person.age = 21; // ✅
person.companyId = 'SP302334'; // ✅
person.id = '10033402'; // ✅
person.name = 'Henry'; // ❌ - name does not exist in Student & Employee

Tuple

Tupleها با استفاده از یک «:» به همراه یک لیست داخل یک براکت، که با استفاده از ویرگول جدا شده‌اند، نشانه‌گذاری می‌شود.

let list: [string, string, number];

list = ['apple', 'banana', 8.75]; // ✅
list = ['apple', true, 8.75]; // ❌ - دومین آرگومان باید از نوع رشته باشد
list = ['apple', 'banana', 10.33, 3]; // ❌ - the tuple specifies a length of 3, not 4

Typeهای اختیاری

شاید نمونه‌هایی وجود داشته باشند که یک پارامتر تابع یا یک ویژگی آبجکت، اختیاری باشد. در این موارد، یک علامت سوال برای مشخص کردن این مقادیر اختیاری استفاده می‌شود.

// پارامتر تابع اختیاری

function callMom(message?: string) {

    if (!message) {

        console.log('Hi mom. Love you. Bye.');

    } else {

        console.log(message);

    }

}



// رابطی که یک آبجکت شامل یک ویژگی اختیاری را توصیف می‌کند

interface Person {

    name: string;

    age: number;

    favoriteColor?: string; // This property is optional

}

باز هم به یاد داشته باشید که یک دوره کامل مربوط به آموزش TypeScript بر روی راکت موجود می‌باشد.

منبع

مقالات پیشنهادی

  • شش طرح زیبا و الهام بخش از codepen

    امروز میخوام چند طرح زیبا از codepen رو بهتون نشون بدم که کار آقای Karim Maaloul . کارهای ایشون با ابزار های مختلفی انجام شده و بسیار بسیار عالی و ز...

    حسام موسوی