انواع پیشرفته در تایپ اسکریپت — از صفر تا صد
تایپ اسکریپت ظرفیتهای نوعی بسیار پیشرفتهای دارد که موجب میشود نوشتن کدهای با نوعبندی دینامیک آسان شود. همچنین موجب تسهیل استفاده از کدهای جاوا اسکریپت موجود میشود، زیرا امکان حفظ ظرفیتهای دینامیک جاوا اسکریپت را در عین استفاده از قابلیت «بررسی نوع» تایپ اسکریپت فراهم میسازد. انواع پیشرفته در تایپ اسکریپت دستهبندیهای مختلفی مانند انواع intersection، انواع union، گارد نوع، انواع تهیپذیر (nullable)، اسامی مستعار نوع و غیره دارند. در این مقاله به بررسی انواع تهیپذیر و اسامی مستعار نوع در تایپ اسکریپت میپردازیم.
انواع تهیپذیر
تایپ اسکریپت برای این که بتوانیم undefined را به یک مشخصه با فلگ strictNullChecks– انتساب دهیم، از انواع تهیپذیر پشتیبانی کرده است. با استفاده از این فلگ نمیتوانیم undefined را به اعضای نوعی که عملگر تهیپذیر الصاق نشده است، انتساب دهیم. برای استفاده از آن کافی است علامت سؤال را پس از نام عضو برای نوعی که میخواهیم استفاده کنیم قرار دهیم.
اگر فلگ strictNullChecks فعال باشد و مقدار یک مشخصه را null یا undefined تعیین کنیم، مثل این است که کار زیر را انجام دادهایم:
1interface Person {
2 name: string;
3 age: number;
4}
5let p: Person = {
6 name: 'Jane',
7 age: null
8}
که خطاهای زیر را تولید میکند:
Type 'null' is not assignable to type 'number'. (2322) input.ts(3, 3): The expected type comes from property 'age' which is declared here on type 'Person'
خطاهای فوق درصورتی که strictNullChecks غیرفعال باشد، ظاهر نمیشوند و کامپایلر تایپ اسکریپت اجازه میدهد که کد کامپایل شود.
اگر فلگ strictNullChecks فعال باشد و بخواهیم undefined را به عنوان مقدار یک مشخصه تعیین کنیم، میتوانیم مشخصه را nullable بکنیم. برای نمونه میتوانیم عضو یک اینترفیس را با کد زیر به صورت تهیپذیر تعیین کنیم:
1interface Person {
2 name: string;
3 age?: number;
4}
5let p: Person = {
6 name: 'Jane',
7 age: undefined
8}
در کد فوق یک علامت سؤال را به عضو age در اینترفیس Person اضافه کردیم تا آن را تهیپذیر سازیم. سپس شیء را تعریف کردیم و میتوانیم age را به صورت undefined تعیین کنیم. ما همچنان نمیتوانیم age را به صورت null تعیین کنیم، چون در این صورت با خطای زیر مواجه خواهیم شد:
Type 'null' is not assignable to type 'number | undefined'. (2322) input.ts(3, 3): The expected type comes from property 'age' which is declared here on type 'Person'
چنان که میبینید، یک نوع تهیپذیر صرفاً یک نوع union بین نوعی که اعلان کردیم و نوع undefined است. این مسئله به آن معنی نیز هست که میتوانیم از گاردهای نوع به همراه آن مانند دیگر انواع union استفاده کنیم. برای نمونه اگر بخواهیم تنها در صورتی age را دریافت کنیم که تعریفشده باشد، میتوانیم کدی مانند زیر بنویسیم:
1const getAge = (age?: number) => {
2 if (age === undefined) {
3 return 0
4 }
5 else {
6 return age.toString();
7 }
8}
در تابع getAge ابتدا بررسی میکنیم آیا پارامتر age به صورت undefined است یا نه. اگر چنین باشد، مقدار 0 بازگشت میدهیم. در غیر این صورت میتوانیم متد ()toString را روی آن فراخوانی کنیم که برای اشیای عددی ارائه شده است.
به طور مشابه میتوانیم مقادیر null را با کد مشابهی حذف کنیم. برای نمونه میتوانیم مانند زیر عمل کنیم:
1const getAge = (age?: number | null) => {
2 if (age === null) {
3 return 0
4 }
5 else if (age === undefined) {
6 return 0
7 }
8 else {
9 return age.toString();
10 }
11}
این کد بسیار مفید واقع میشود، زیرا انواع تهیپذیر از این که null با strictNullChecks انتساب یابد استثنا شدهاند، بنابراین اگر بخواهیم null بتواند به صورت یک مقدار برای پارامتر age ارسال شود، باید null را به نوع union اضافه کنیم. همچنین میتوانیم 2 بلوک if نخست را به صورت یک بلوک واحد ترکیب کنیم:
1const getAge = (age?: number | null) => {
2 if (age === null || age === undefined) {
3 return 0
4 }
5 else {
6 return age.toString();
7 }
8}
اسامی مستعار نوع
اگر بخواهیم نام جدیدی برای یک نوع موجود ایجاد کنیم، میتوانیم یک «اسم مستعار نوع» (Type Aliase) به آن نوع اضافه کنیم. اسم مستعار میتواند برای انواع مختلفی مورد استفاده قرار گیرد که شامل انواع ابتدایی، union-ها، چندتاییها و دیگر انواع میشود. برای ایجاد یک اسم مستعار نوع میتوانیم از کلیدواژه type استفاده کنیم. برای نمونه اگر بخواهیم یک اسم مستعار به نوع union اضافه کنیم، میتوانیم کدی مانند زیر بنویسیم:
1interface Person {
2 name: string;
3 age: number;
4}
5interface Employee {
6 employeeCode: number;
7}
8type Laborer = Person & Employee;
9let laborer: Laborer = {
10 name: 'Joe',
11 age: 20,
12 employeeCode: 100
13}
اعلان laborer همانند آن است که مستقیماً از نوع intersection برای نوع بندی شیء laborer مانند زیر استفاده کرده باشیم:
1let laborer: Person & Employee = {
2 name: 'Joe',
3 age: 20,
4 employeeCode: 100
5}
امکان اعلان اسامی مستعار نوع برای انواع مقدماتی مانند هر نوع دیگری مهیا شده است. برای نمونه میتوانیم نوع union را با انواع مقدماتی دیگری مانند کد زیر بسازیم:
1type PossiblyNumber = number | string | null | undefined;
2let x: PossiblyNumber = 2;
3let y: PossiblyNumber = '2';
4let a: PossiblyNumber = null;
5let b: PossiblyNumber = undefined;
در کد فوق، نوع PossiblyNumber میتواند یک عدد، رشته، null یا undefined باشد. اگر تلاش کنیم درکدی مانند زیر یک مقدار غیر معتبر مانند مقدار بولی را به آن انتساب دهیم:
1let c: PossiblyNumber = false;
با خطای زیر مواجه میشویم:
1Type 'false' is not assignable to type 'PossiblyNumber'. (2322)
این رفتار دقیقاً مشابه هر نوع انتساب مقدار غیر معتبر دیگر است. همچنین میتوانیم نوع ژنریک را در اسامی مستعار نوع بگنجانیم. برای نمونه میتوانیم کدی مانند زیر بنویسیم:
1type Foo<T> = { value: T };
اسامی مستعار نوع ژنریک نیز میتوانند در مشخصههای یک نوع مورد ارجاع قرار گیرند. به این جهت میتوانیم کدی مانند زیر بنویسیم:
1type Tree<T> = {
2 value: T;
3 left: Tree<T>;
4 center: Tree<T>;
5 right: Tree<T>;
6}
سپس میتوانیم از نوع Tree همچنان که در کد زیر میبینید استفاده کنیم:
1type Tree<T> = {
2 value: T,
3 left: Tree<T>;
4 center: Tree<T>;
5 right: Tree<T>;
6}
7let tree: Tree<string> = {} as Tree<string>;
8tree.value = 'Jane';
9tree.left = {} as Tree<string>
10tree.left.value = 'Joe';
11tree.left.left = {} as Tree<string>;
12tree.left.left.value = 'Amy';
13tree.left.right = {} as Tree<string>
14tree.left.right.value = 'James';
15tree.center = {} as Tree<string>
16tree.center.value = 'Joe';
17tree.right = {} as Tree<string>
18tree.right.value = 'Joe';
19console.log(tree);
دستور console.log برای مقدار tree در خط آخر خروجی زیر را در اختیار ما قرار میدهد:
1{
2 "value": "Jane",
3 "left": {
4 "value": "Joe",
5 "left": {
6 "value": "Amy"
7 },
8 "right": {
9 "value": "James"
10 }
11 },
12 "center": {
13 "value": "Joe"
14 },
15 "right": {
16 "value": "Joe"
17 }
18}
سخن پایانی
انواع تهیپذیر در صورتی که بخواهیم undefined را به یک مشخصه نسبت دهیم، در زمان فعال بودن فلگ strictNullChecks در پیکربندی کامپایلر تایپ اسکریپت، مفید واقع میشوند. در واقع نوع تهیپذیر صرفاً یک نوع یونیون بین هر نوع مجود و undefined است. این نوع با علامت سؤال پس از نام مشخصه نشان داده میشود. این بدان معنی است که میتوانیم از گاردهای نوع مانند هر نوع یونیون دیگر به همراه آن استفاده کنیم. توجه کنید که انواع تهیپذیر تنها در مواردی لازم هستند که فلگ strictNullChecks روشن باشد. اسامی مستعار نوع به ما امکان میدهند که نام جدیدی برای انواعی که از قبل موجود است تعیین کنیم. همچنین میتوانیم از ژنریکها به همراه اسامی مستعار نوع استفاده کنیم، اما نمیتوانیم آنها را به صورت انواع مستقل مورد استفاده قرار دهیم.
اگر این مطلب برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای JavaScript (جاوا اسکریپت)
- مجموعه آموزشهای برنامهنویسی
- آموزش JavaScript ES6 (جاوا اسکریپت)
- راهنمای جامع تایپ اسکریپت (Typescript) — از صفر تا صد
- درک انواع در تایپ اسکریپت — به زبان ساده
==