تایپ آرایه و Tuple ها (Array & Tuple Type) در تایپ اسکریپت

27 اسفند 1398
تایپ آرایه و Tuple ها (Array & Tuple Type) در تایپ اسکریپت

تایپ آرایه ها و Tuple ها در تایپ اسکریپت

پس از اشیاء نوبت به آرایه ها می رسد و باید با تایپ آن ها در تایپ اسکریپت آشنا شویم. معمولا در تایپ اسکریپت دو نوع type برای آرایه ها در نظر گرفته می شود: منعطف و سخت. بیایید از همان مثال جلسه ی قبل برای درک این تایپ ها استفاده کنیم:

const person = {
  name: 'Maximilian',
  age: 30,
  hobbies: ['Sports', 'Cooking']
};

من به همان شیء جلسه ی قبل یک خصوصیت دیگر به نام hobbies اضافه کرده ام که به معنی «تفریحات» است و دو مقدار sports (ورزش) و cooking (آشپزی) را در قالب یک آرایه برایش قرار داده ام. اگر موس خود را روی hobbies ببرید type آن برایتان نمایش داده می شود:

نوع داده ی جدید برای آرایه ها
نوع داده ی جدید برای آرایه ها

همانطور که می بینید تایپ این آرایه از نوع []string می باشد! ما قبلا چنین تایپی را ندیده بودیم. این syntax روش تایپ اسکریپت برای مشخص کردن تایپ آرایه ها می باشد: ابتدا علامت [] را داریم و سپس نوع داده ای که درون آرایه ذخیره شده است را داریم که در این مثال می شود String چرا که مقادیر درون hobbies رشته هستند.

مثلا فرض کنید که یک متغیر جدید تعریف می کنیم و می خواهیم تایپ آن را مشخص کنیم:

const person = {
  name: 'Maximilian',
  age: 30,
  hobbies: ['Sports', 'Cooking']
};

let favoriteActivities: string[];

همانطور که می بینید متغیر favoriteActivities تعریف شده اما آن را مقداردهی نکرده ام و فقط type اش را مشخص کرده ام. این کد به ما می گوید که مقدار درون favoriteActivities باید اولا آرایه باشد، دوما رشته باشد بنابراین کد زیر با خطا روبرو می شود:

let favoriteActivities: string[];
favoriteActivities = 'Sports';

چرا؟ به دلیل اینکه sports فقط یک رشته است و آرایه نیست. برای حل این مشکل می توانیم آن را تبدیل به یک آرایه کنیم:

let favoriteActivities: string[];
favoriteActivities = ['Sports'];

همچنین اگر به همین آرایه یک عدد اضافه کنیم با خطا روبرو می شویم:

let favoriteActivities: string[];
favoriteActivities = ['Sports', 1];

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

let favoriteActivities: any[];
favoriteActivities = ['Sports', 1];

با انجام این کار خطا از بین می رود اما تمام مزایای تایپ اسکریپت را از دست دادیم! چرا؟ نوع داده ی any یعنی هر چیزی می تواند در این قسمت قرار بگیرد (رشته، عدد، آرایه و...). از طرفی یکی از اهداف اصلی تایپ اسکریپت اضافه کردن type یا نوع داده است و اگر از any استفاده کنیم، عملا انگار از جاوا اسکریپت استفاده کرده ایم و دیگر نیازی به تایپ اسکریپت نداریم. ما در جلسات بعد نگاه دقیق تری به any می اندازیم اما فعلا باید بدانید که any تایپ خاصی است که استفاده های بسیار خاصی دارد و در اکثر مواقع باید تا حد امکان از آن دوری کنید تا مزایای تایپ اسکریپت را از دست ندهید.

حالا فرض کنید بخواهیم با یک حلقه ی for در hobbies گردش کنیم و مقادیر آن را console.log کنیم. می توانیم به سادگی بگوییم:

for (const hobby of person.hobbies) {
  console.log(hobby);
}

تا اینجای کار همان جاوا اسکریپت خودمان را نوشته ایم و کار خاصی نکرده ایم. اگر در حال حاضر tsc app.ts را اجرا کنیم دو مقدار Sports و Cooking را در کنسول مرورگر دریافت می کنیم. نکته ی جالب در تایپ اسکریپت این است که در کد بالا می توانیم از هر متد رشته ای روی hobby استفاده کنیم و visual studio code از آن پشتیبانی می کند:

پشتیبانی از متد های رشته ای
پشتیبانی از متدهای رشته ای

همانطور که می بینید VSCode می تواند به سادگی تشخیص دهد که hobby رشته است بنابراین متدهای رشته ای را برای استفاده ی ما آماده می کند. تایپ اسکریپت متوجه می شود که اگر hobbies یک آرایه است و تایپ آن آرایه ی رشته ای می باشد، بنابراین هر عضو آن (hobby) یک رشته ی ساده خواهد بود و متدها را آماده می کند. با این حساب این کد صحیح می باشد:

for (const hobby of person.hobbies) {
  console.log(hobby.toUpperCase());
}

اما کد زیر دیگر صحیح نیست:

for (const hobby of person.hobbies) {
  console.log(hobby.map()); // !!! ERROR !!!
}

چرا؟ به دلیل اینکه تایپ اسکریپت نوع یا همان type متغیر hobby را می داند و می فهمد که hobby آرایه نیست بنابراین متد map که روی آرایه ها صدا زده می شود با آن همخوانی نداشته و به عنوان خطا زیر map را خط می کشد.

Tuple چیست؟

هر type ای که تا اینجای کار یاد گرفته ایم توسط خود جاوا اسکریپت پشتیبانی می شود و چیز جدیدی نیست (البته فقط در سطح درک و شناسایی) اما از این جلسه به بعد به سراغ تایپ هایی می رویم که در جاوا اسکریپت موجود نیستند. اولین آن ها Tuple (تلفظ: تیوپِل – تیو مثل «نیو» در نیویورک). Tuple ها در برخی از زبان های برنامه نویسی دیگر مانند پایتون حضور دارند اما در جاوا اسکریپت موجود نیستند. یک مثال از Tuple ها به شکل زیر است:

[1,2]

احتمالا با خودتان می گویید این که یک آرایه است! حرفتان درست است. Tuple ها در واقع آرایه هایی با طول و تایپ ثابت هستند. بگذارید نحوه ی استفاده از آن ها را به شما نشان بدهم. فرض کنید یک خصوصیت دیگر به همان مثال خودمان اضافه کنیم:

const person = {
  name: 'Maximilian',
  age: 30,
  hobbies: ['Sports', 'Cooking'],
  role: [2, 'author']
};

فرض کنید خصوصیت role قرار است سطح دسترسی و مسئولیت افراد در سایت ما را مشخص کند. به طور مثال در کد بالا فرض کرده ایم که عدد 2 برابر با سطح author یا نویسنده است و افراد این سطح می توانند در سایت ما مطلب بنویسند. قسمت عددی برای استفاده در عملیات های بررسی در سمت سرور است و قسمت author برای نمایش در Front-end سایت تا کاربران بفهمند وضعیت هر فرد چیست. چنین آرایه ای همیشه باید دو عضو داشته باشد که اولی عدد و دومی رشته است.

اگر در حال حاضر موس را روی role ببرید تایپ آن را مشاهده خواهید کرد:

تایپ role
تایپ role

تا به حال این نوع از type را مشاهده نکرده ایم. به این نوع از تایپ ها union type (به معنی تایپ یا نوع اتحاد) می گوییم که چند تایپ خاص را با هم جمع می کنند. در مورد این نوع از تایپ ها بعدا توضیح خواهیم داد و فعلا کاری با آن ها نداریم. مهم اینجاست که تایپ اسکریپت متوجه می شود که role یک آرایه است که دو نوع عدد و رشته را می گیرد.

متاسفانه در حال حاضر می توانیم دستور زیر را اجرا کنیم:

const person = {
  name: 'Maximilian',
  age: 30,
  hobbies: ['Sports', 'Cooking'],
  role: [2, 'author']
};

person.role.push('admin');

با دستور بالا، آرایه ی ما سه عضو می گیرد. همچنین کد زیر نیز کاملا صحیح است:

const person = {
  name: 'Maximilian',
  age: 30,
  hobbies: ['Sports', 'Cooking'],
  role: [2, 'author']
};

person.role.push('admin');
person.role[1] = 10;

یعنی می توانیم ایندکس اول (عضو دوم) را با یک عدد جا به جا کنیم! متاسفانه تایپ اسکریپت تشخیص نمی دهد که این کار مد نظر ما نیست. چرا؟ دوباره به تایپ role نگاه کنید:

تایپ role
تایپ role

تایپ role فقط می گوید که این یک آرایه است و مقادیر درون آن می توانند عدد یا رشته باشند. نه تعداد مشخص کرده ایم و نه اینکه هر نوع عضو اول باشد یا عضو دوم. برای چنین حالتی که به مشکل برخورده ایم Tuple ها عالی هستند!

اینجاست که می توانیم از Tuple ها استفاده کرده و تایپ role را به صورت دستی مشخص کنیم:

const person: {
  name: string;
  age: number;
  hobbies: string[];
  role: [number, string];
} = {
  name: 'Maximilian',
  age: 30,
  hobbies: ['Sports', 'Cooking'],
  role: [2, 'author']
};

زمانی که از این ساختار استفاده کنیم (یعنی [number, string]) به تایپ اسکریپت می گوییم که این مقدار یک Tuple است بنابراین فقط دو عضو دارد. همچنین اعلام می کنیم که عضو اول باید عدد و عضو دوم باید رشته باشد. این مورد از معدود مواردی است که مشخص کردن type به صورت دستی هیچ منعی ندارد و می توانید از آن استفاده کنید (البته در شرایط دیگر هم به خطا برنمی خورید بلکه اضافه نویسی می کنید). با این حساب اگر کد زیر را بنویسیم با خطا روبرو می شویم:

person.role[1] = 10;

اما کد زیر بدون خطا اجرا می شود:

person.role.push('admin');

دلیل آن هم استثناء بودن push است. دستور push استثنائا در Tuple ها مجاز است و می توانید از آن استفاده کنید. بنابراین تایپ اسکریپت نمی تواند متوجه این خطا شود. البته کد زیر خطا خواهد بود:

person.role = [0, 'admin', 'user'];

به دلیل اینکه اعلام کرده ایم که role فقط دو عضو خواهد داشت ولی اینجا سه عضو را پاس داده ایم. یادتان باشد که فقط push استثناء است اما بقیه ی موارد تشخیص داده می شوند.

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

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

نظری
15 فروردین 1399
دوست عزیز تلفظ درست tuple - تاپل هستش نه تیوپل!!

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

امیر زوارمی
27 فروردین 1399
سلام دوست عزیز، بعضی ها اعتقاد دارند که هر دو تلفظ صحیح هست: https://english.stackexchange.com/questions/12980/how-to-pronounce-tuple اما دیکشنری های Oxford و Cambridge به صورت /ˈtjuːp(ə)l/ آوردن. تلفظ های آمریکایی و بریتانیایی در این لینک از دیکشنری کمبریج موجود هست: https://dictionary.cambridge.org/dictionary/english/tuple

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

صادق
12 دی 1398
سلام فکر کنم اشتباه کردید آقای زوارمی مگه []string نمیشه تایپ رشته؟

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

امیر زوارمی
15 دی 1398
سلام دوست عزیز نه علامت های [] یعنی آرایه. اون قسمت string برای عناصر داخل آرایه هست، یعنی یک آرایه ای که مقادیر داخلش رشته ای هستند

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

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