سرعت و سادگی زبان برنامه نویسی جاوا اسکریپت از مزیتهای اصلی این زبان به حساب میآید، اما بیشتر کتابها و مستندات علمی روی این قضیه تأکید دارند که جاوا اسکریپت زبانی کامل نیست. ولی با این حال امروزه جاوا اسکریپت چه در برنامه نویسی سمت سرور و چه در برنامه نویسی سمت کلاینت کاربردهای خاص خودش را دارد. امروزه تایپ اسکریپت به عنوان راهحلی برای رفع محدودیتهای جاوا اسکریپت توسعه یافته است تا کم و کاستیهای جاوا اسکریپت را به عنوان زبانی «بدون نیاز به تعیین صریح نوع» (Loosely Typed) پشت سر بگذارد. در این مطلب در رابطه با اینکه تایپ اسکریپت چیست و جنبههای مختلف آن چه هستند اطلاعات جامعی ارائه شده است.
این مطلب برای سه نوع برنامهنویس میتواند بسیار مفید واقع شود، ابتدا برای توسعهدهندگان جاوا اسکریپت که میخواهند بدانند «TypeScript» چگونه کار میکند. دوم برای کسانی که توسعهدهنده زبانهای دیگر هستند و در مورد جاوا اسکریپت شک و شبه دارند که آیا تایپ اسکریپت محدودیتهای آن را برطرف میکند یا خیر و سوم کسانی که با تایپ اسکریپت آشنا هستند و از آن نیز استفاده کردهاند، اما میخواهند مهارتهای خود را در آن بهبود ببخشند.
پیش نیازهای یادگیری تایپ اسکریپت
قبل از اینکه به اصل مسئله و آموزش برخی از ابعاد مختلف تایپ اسکریپت پرداخته شود، بهتر است ابتدا محیطکد ادیتور آمادهسازی شود. برای این هدف، کد ادیتور خود TypeScript میتواند کاربردی و مناسب باشد. اما با این حال برخی از کاربران میخواهند آن را همراه با کتابخانهها و فریمورکهای جاوا اسکریپت (مانند Angular ،Vue.js و ری اکت) استفاده کنند.
برای این هدف نیز به نصب «Node.js» و «NPM» وجود دارد که باید برای این هدف نصب کننده آن را از آدرس [+] دانلود کرد. هنگامی که Node/NPM نصب شدند، حال نوبت به نصب کامپایلر با استفاده از NPM فرا میرسد که این کار به صورت زیر انجام خواهد شد.
> npm install typescript -g
حال که تایپ اسکریپت روی سیستم نصب شده، میتوان اولین فایل خود را با نام «{filename}.Ts» ایجاد کرد. «Tsc» مخفف عبارت «TypeScript Compiler» است و برای کامپایل کردن فایل تایپ اسکریپت نیاز به فراخوانی با نام فایل وجود دارد. این کار به صورت زیر قابل انجام خواهد بود.
> tsc index.ts
اگر فرایند کامپایل کردن موفقیتآمیز باشد، فایلی به نام «Index.js» ایجاد میشود. برای ویرایشگرهای رایج تایپ اسکریپت این کامپایلر به صورت پیشفرض فعال است. برای مثال در «ویژوال استودیو کد» (Visual Studio Code) این کامپایلر بررسی خطا و «IntelliSense» را بدون هیچ پسوندی به کار خواهد برد. دو تصویر زیر این مسئله را در VSC نشان میدهند.
در تصویر زیر هم مشاهده میشود که سیستم پیشنهاددهی نیز به درستی عمل میکند.
ویژوال استودیو به روشی مشابه کار میکند. همانطور که در شکل زیر نشان داده شده، تایپ اسکریپت در آن فعال و قابل استفاده است.
در این شرایط هیچ پسوندی برای فایل تایپ اسکریپت لازم نیست. رفتار پیشفرض ویرایشگر ویژوال استودیو به صورت خودکار کدهای تایپ اسکریپت را کامپایل میکند. همچنین برای غیرفعال کردن این حالت به منظور عدم کامپایل خودکار کدهای تایپ اسکریپت در ویژوال استودیو میتوان فایل «Csproj» را ویرایش کرده و عنصر «TypeScriptCompileBlocked» را برای این کار به آن اضافه کرد. ویرایش این فایل به صورت زیر قابل انجام است.
net6.0 enable true ... ...
تا به اینجای مطلب در رابطه با اینکه پیشنیازهای تایپ اسکریپت چیست و چگونه میتوان کدهای آن را کامپایل کرد، مطالبی ارائه شد. در بخش بعدی در ارتباط با اینکه رابطه بین جاوا اسکریپت و تایپ اسکریپت چیست توضیحاتی ارائه داده خواهد شد.
رابطه بین جاوا اسکریپت و تایپ اسکریپت چیست؟
در پاسخ به این پرسش که رابطه بین جاوا اسکریپت و تایپ اسکریپت چیست میتوان گفت تایپ اسکریپت نسبت به جاوا اسکریپت یک فوقمجموعه یا فرامجموعه (یعنی مجموعهای بسیار بزرگتر از جاوا اسکریپت) محسوب میشود. تایپ اسکریپت از جاوا اسکریپت نشأت گرفته و با بسط و گسترش دادن آن پدید آمده است. این یعنی که برای نوشتن برنامهای با این زبان، کاربر ابتدا کدهای خود را در تایپ اسکریپت مینویسد و سپس با استفاده از کامپایلر تایپ اسکریپت آن را به کدهای جاوا اسکریپت کامپایل میکند.
زمانی که کاربر کدهای جاوا اسکریپت را با موفقیت از کامپایلر تایپ اسکریپت دریافت کرد، میتوان آن را در هر محیط دلخواهی که از جاوا اسکریپت پشتیبانی میکند، بدون هیچ مشکلی اجرا کرد. فایلهای TypeScript به جای پسوند «js» که مختص فایلهای جاوا اسکریپت هستند، پسوند «ts» دارند.
تایپ اسکریپت از همان سینتکس جاوا اسکریپت استفاده میکند و سینتکسهای دیگری هم برای پشتیبانی از Typeها در این زبان اضافه شده است. یک برنامه جاوا اسکریپت که به لحاظ نحوی (سینتکس) هیچگونه خطایی ندارد، در واقع نوعی برنامه تایپ اسکریپت نیز به حساب میآید. در اصل میتوان گفت که همه برنامههای جاوا اسکریپت نوعی برنامه تایپ اسکریپت نیز هستند. تصویر زیر رابطه بین جاوا اسکریپت و تایپ اسکریپت را به خوبی نشان میدهد.
در واقع در داخل جاوا اسکریپت ابزارهایی به نام «linters» وجود دارند که مشخص میکنند کدهای جاوا اسکریپت مشکل دارند یا خیر و این بیشتر به خاطر «بدون نیاز به تعیین صریح نوع» (Loosely Typed) بودنِ جاوا اسکریپت است. این بررسی شامل خطاهای نحوی و همچنین مجموعهای از قوانین قابل تنظیم میشود. وقتی میگوییم جاوا اسکریپت «بدون نیاز به تعیین صریح نوع» است، منظور این است که متغیرهای آن هنگام ایجاد به نوع خاصی گره نمیخورند. به مثال زیر در این رابطه توجه کنید.
let a = "Shawn";
console.log(typeof a); // string
a = 1;
console.log(typeof a); // number
در مثال بالا متغیر a
به این دلیل ایجاد شده که به آن رشته اختصاص داده شده است و حال اگر به آن عدد اختصاص دهند، تبدیل به نوع عددی میشود. این ویژگی به بخشهای دیگر زبان نیز گسترش پیدا میکند. برای مثال، پارامترهای تابع زیر در جاوا اسکریپت همگی اختیاری هستند و قبل از استفاده از آنها باید مطمئن شویم که مشکل خاصی ندارند.
function writeName(name) {
// Could be empty, null, or undefined
if (name) {
console.log(name);
}
}
writeName("Bob");
writeName();
به صورت کلی میتوان گفت تایپ اسکریپت به این دلیل توسعه یافته است تا کاربران اطمینان حاصل کنند که مفروضات موجود در کدهای جاوا اسکریپت آنها تأثیری بر کیفیت کارشان نخواهد داشت. مزایای تایپ اسکریپت ممکن است در پروژههای کوچک چندان قابل رؤیت نباشد، اما در پروژههایی با مقیاس بزرگتر این مزایا به خوبی خودشان را نشان میدهند.
تایپ اسکریپت چیست؟
در هسته خود، تایپ اسکریپت نوعی بررسی کننده نوع ایستا به حساب میآید که رسالت آن پوشش کاستیهای جاوا اسکریپت است. در واقع تایپ اسکریپت بررسی نوع را به مرحله کامپایل اضافه میکند تا این کمیها و کاستیها را پوشش دهد. این کار با اضافه کردن سیستم تعیین نوع و سایر ویژگیهای آیندهنگرانه به جاوا اسکریپت قابل انجام است. در واقع همانطور که در بالا نیز به آن اشاره شد، تایپ اسکریپت تنها مجموعهای فوقالعاده از جاوا اسکریپت بوده و رسالت اصلی آن مقیاسپذیرتر کردن جاوا اسکریپت است.
ایجاد کردن زبانهایی که به جاوا اسکریپت اضافه میشوند، ایده جدیدی نیست، اما مسئله در مورد تایپ اسکریپت کاملاً فرق میکند؛ زیرا TypeScript از جاوا اسکریپت معتبرتر است و به علاوه اینکه خود جاوا اسکریپت را شامل میشود. علاوه بر این، تایپ اسکریپت ویژگیهای کاملاً جدیدی را نیز به جاوا اسکریپت اضافه میکند تا مدیریت پروژههای بزرگ را آسانتر کند. در ادامه این مسئله در قالب مثالی ارائه شده است.
مثالی از تایپ اسکریپت
در اینجا مثالی از کد نویسی تایپ اسکریپت ارائه خواهد شد تا کاربر بتواند به صورت عینی این قضیه را درک کند که تایپ اسکریپت چیست و چگونه کار میکند. برای شروع، مثال فرضی زیر در نظر گرفته شده است.
const element = document.getElementById("someObject");
element.addEventListener("click", function () {
element.classList.toggle("selected");
});
قطعه کد بالا، قطعه کدی معتبر از جاوا اسکریپت است اما خروجی آن چه خواهد بود؟ حال به قطعه کد زیر دقت شود:
"use strict";const element = document.getElementById("someObject");
element.addEventListener("click", function () {
element.classList.toggle("selected");
});
آیا تفاوتی بین این دو قطعه کد وجود دارد؟ در قطعه کد پایینتر use strict
اضافه شده است و در واقع این قطعه کدی ساده از جاوا اسکریپت است و در همان حال نوعی قطعه کد معتبر تایپ اسکریپت هم به حساب میآید. در واقع میتوان از همه مزایا و ویژگیهای جاوا اسکریپت در تایپ اسکریپت نیز بهره برد.
در ادامه مثالی دیگر از این موضوع و این بار با استفاده از «اطلاعات نوع» (Type Information) در تایپ اسکریپت ارائه خواهد شد. قطعه کد این مثال در ادامه آمده است.
// TypeScript
// The collection
const theList = new Array();
// Function to add items
function addToCollection(item: string) {
theList.push(item);
}
// Use the typed function
addToCollection("one");
addToCollection("two");
addToCollection(3); // TypeScript Error
در مثال بالا، «آرگومان عمومی» (Generic Argument) موجود در آرایه مشخص میکند که لیست موجود فقط باید رشتهها را بپذیرد. همچنین کاربر در تابع مشخص میکند که تابع فقط رشته را برای پارامتر بگیرد. در این مثال مشخص نیست که تابع push
در theList
فقط باید رشته را بگیرد یا خیر؛ هنگامی که این کد اجرا میشود، دو فراخوانی اول بدون هیچ مشکلی با رشتهها کار میکنند، ولی فراخوانی سوم نوعی خطا در طول کامپایل تایپ اسکریپت ارائه میدهد. اما این فراخوانی چگونه بر خروجی این کامپایلر تأثیر گذاشته است؟
// Resulting JavaScript
"use strict";
// The collection
const theList = new Array();
// Function to add items
function addToCollection(item) {
theList.push(item);
}
// Use the typed function
addToCollection("one");
addToCollection("two");
addToCollection(3); // TypeScript Error
در قطعه کد فوق، اگرچه عملکرد بررسی نوع در تایپ اسکریپت دارای فایل منبع موجود است، اما هیچکدام به جاوا اسکریپت ترجمه نخواهند شد. مزایای اصلی تایپ اسکریپت در مورد بررسی نوع در زمان کامپایل این است که هیچ تلاشی نمیکند که جاوا اسکریپت را به زبانی با تایپ قوی (تعیین نوع ایستا) تبدیل کند. به همین دلیل در پروژههای بزرگ با سطوحی پیچیده، استفاده از تایپ اسکریپت بسیار مفید است.
یکی دیگر از مزایای اصلی تایپ اسکریپت این است که کدهای آن بدون نیاز به محیط جاوا اسکریپت قابل نوشتن هستند. در ادامه مثالی دیگر از تایپ اسکریپت مورد بررسی قرار گرفته است.
// TypeScript
class Animal {
name = "";
age = 0;
fed = false;
feed(food: string) {
this.fed = true;
}
}
در مثال فوق، کاربر در حال ایجاد کلاسهایی است که در نسخههای قدیمی جاوا اسکریپت پشتیبانی نمیشوند. با استفاده از کدنویسی تایپ اسکریپت میتوان سطح جاوا اسکریپت را از لحاظ نسخههای مختلف آن مشخص کرد. برای مثال اگر کاربر بخواهد از «ECMAScript 2015» استفاده کند در آن نسخه کلاسهای جاوا اسکریپت پشتیبانی میشوند. مثال زیر این موضوع را نشان میدهد.
// ECMAScript 2015
"use strict";
class Animal {
constructor() {
this.name = "";
this.age = 0;
this.fed = false;
}
feed(food) {
this.fed = true;
}
}
اگر این مثال برای مرورگرهای (مانند ECMAScript 5) قدیمی هدف قرار داده شود، قضیه کاملاً متفاوت خواهد بود و قطعه کد این مثال به صورت زیر تغییر خواهد کرد:
// ECMAScript 5
"use strict";
var Animal = /** @class */ (function () {
function Animal() {
this.name = "";
this.age = 0;
this.fed = false;
}
Animal.prototype.feed = function (food) {
this.fed = true;
};
return Animal;
}());
مزایای تایپ اسکریپت چیست؟
تا به اینجا توضیح داده شد که تایپ اسکریپت چیست و چه رابطهای با جاوا اسکریپت دارد. در این بخش نوبت به بررسی این مسئله رسیده است که مزایای استفاده از تایپ اسکریپت چیست و چرا با وجود جاوا اسکریپت باید از آن استفاده کرد. در درجه اول، تایپ اسکریپت تعیین نوع اختیاری را به جاوا اسکریپت اضافه و ویژگیهای برنامهریزی شده جاوا اسکریپت آینده یا «ECMAScript Next» را در کنار جاوا اسکریپت فعلی پیادهسازی میکند.
به صورت کلی به عنوان مزایای تایپ اسکریپت میتوان به مواردی اشاره کرد که در ادامه بیان خواهند شد.
افزایش بهرهوری و کاهش اشتباهات
بررسی نوع به کمک تایپ اسکریپت میتواند از بروز اشتباهات جلوگیری کند و بهرهوری را افزایش دهد. با استفاده از بررسی نوع میتوان به جای زمان اجرا، باگها را در زمان کامپایل پیدا کرد. برای مثال در تابع زیر دو عدد x
و y
با هم جمع میشوند:
function add(x, y) {
return x + y;
}
در مثال فوق اگر عناصر ورودی از HTML دریافت و به تابع ارسال شوند، ممکن است نتیجهای غیرمنتظره داشته باشد.
let result = add(input1.value, input2.value);
console.log(result); // result of concatenating strings
برای مثال، اگر کاربر اعداد 10
و 20
را وارد کند، تابع add()
به جای 30
، عدد 1020
را بازمیگرداند. این نتیجه به این دلیل حاصل میشود که input1.value
و input2.value
نه از نوع عددی، بلکه از نوع رشتهای هستند. هنگامی که از عملگر +
برای اضافه کردن دو رشته استفاده شود، آنها را به رشتهای واحد تبدیل میشوند. زمانی که از تایپ اسکریپت برای تعیین صریح نوع پارامترهایی مانند زیر استفاده شود، کارایی و دقت بهبود خواهد یافت.
function add(x: number, y: number) {
return x + y;
}
در این تابع نوع اعداد به پارامترها اضافه شدهاند و در اینجا تابع add()
فقط اعداد را میپذیرد. وقتی تابع به صورت قطعه کد زیر فراخوانی شود، چه اتفاقی خواهد افتاد؟
let result = add(input1.value, input2.value);
اگر کد تایپ اسکریپت در جاوا اسکریپت کامپایل شود، در نتیجه کامپایلر تایپ اسکریپت با خطا مواجه میشود، از این رو میتوان از بروز خطا با تایپ اسکریپت جلوگیری کرد.
استفاده از ویژگی های جاوا اسکریپت مدرن در تایپ اسکریپت
تایپ اسکریپت از ویژگیهای آتی برنامهریزی شده در «ES Next» (جاوا اسکریپت آینده) برای موتورهای جاوا اسکریپت فعلی پشتیبانی میکند. این یعنی کاربران میتوانند از ویژگیهای جدید جاوا اسکریپت قبل از اینکه مرورگرهای وب (یا سایر محیطها) بهطور کامل از آنها پشتیبانی کنند، بدون هیچ مشكلی بهره ببرند.
هر ساله، «TC39» چندین ویژگی جدید را برای ECMAScript منتشر میکند که استاندارد جدید جاوا اسکریپت است. پیشنهادهای ویژه TC39 معمولاً در پنج مرحله تائید و به جاوا اسکریپت اضافه میشوند که این مراحل به صورت زیر هستند:
- مرحله ۰: «Strawperson»
- مرحله ۱: پیشنهاد یا پروپوزال
- مرحله ۲: پیشنویس
- مرحله ۳: کاندید شدن
- مرحله ۴: اتمام
تایپ اسکریپت به طور کلی از ویژگیهایی پشتیبانی میکند که در مرحله ۳ هستند.
معایب تایپ اسکریپت چیست؟
در خصوص معایب تایپ اسکریپت باید گفت، تایپ اسکریپت نسبتاً جدید است و از برخی ابزارها و کتابخانهها پشتیبانی نمیکند و یادگیری و درک آن به زمان زیادی نیاز دارد. همچنین تایپ اسکریپت از همه مرورگرها پشتیبانی نمیکند و برای اجرا به یک مرحله کامپایل نیاز دارد که این به خودی خود به پیچیدگی آن اضافه میکند. از طرف دیگر دیباگ کردن کدهای تایپ اسکریپت کمی دشوار است.
ویژگی های تایپ اسکریپت
اکنون که پاسخ داده شد تایپ اسکریپت چیست و چه رسالتی دارد، نوبت به بررسی ویژگیهای آن فرا میرسد. همچنین در این بخش نحوه استفاده از تایپ اسکریپت نیز بیان خواهد شد تا کاربر درک عمیقی از اینکه تایپ اسکریپت چیست پیدا کند.
بررسی نوع در تایپ اسکریپت
بررسی نوع در تایپ اسکریپت به صورت حاشیهنویسی مشخص میشود که در مثال زیر این موضوع مشخص شده است.
let theName: string = "Shawn";
در قطعه کد فوق با استفاده از علامت دونقطه و سپس با تعیین نوع میتوان برای تایپ اسکریپت مشخص کرد که این متغیر همیشه باید «رشته» (استرینگ | String) باشد. اگر برای این متغیر دادهای غیر از رشته اختصاص یابد، «خطای نوع» (Error Type) در تایپ اسکریپت اتفاق خواهد افتاد. مثال زیر در این رابطه ارائه شده است:
let theName: string = "Shawn";
theName = 1;
برای این مثال، کامپایلر تایپ اسکریپت خروجی زیر را به کاربر ارائه خواهد داد:
D:writingCoDeMagTypeScriptcode>tsc index.ts index.ts:3:1 - error TS2322: Type 'number' is not assignable to type 'string'. 3 theName = 1; ~~~~~~~ Found 1 error in index.ts:3
در این رابطه میتوان گفت کاربر نیازی به تعیین نوع ندارد، زیرا تایپ اسکریپت هنگام ایجاد متغیرها نوع داده را از انتساب آن استنتاج میکند.
let theName = "Shawn";
// identical to
let theName: string = "Shawn";
در بیشتر مواقع فقط زمانی باید تعیین نوع انجام شود که مقدار اولیه اختصاص داده شنده باشد. این شرایط برای توابع نیز بسیار مفید خواهد بود. مثال زیر در این رابطه آورده شده است.
function write(message: string) {
// no need to test for data type
console.log(message);
}
مثال بالا بیان میکند که هر فردی از تابع write
استفاده میکند، اگر بخواهد پیغام write
را با چیزی غیر از رشته فراخوانی کند، با خطا مواجه میشود. همچنین تایپ اسکریپت این قابلیت را دارد که هنگام تعریف اشیا نوع آنها را نیز استنباط کند. مثال زیر در این خصوص ارائه شده است.
let person = {
firstName: "Shawn",
lastName: "Wildermuth",
age: 53
};
person.age = "55"; // Won't Work
برای آرایهها نیز تایپ اسکریپت به همین منوال عمل میکند. برای مثال تایپ اسکریپت در مثال زیر فرض میکند آرایه تعریف شده، آرایهای از رشتهها است.
let people = [ "one", "two", "three" ];
people.push(1); // won't work
این مسئله برای آرایههای اشیا نیز صدق میکند.
راهنمای جامع تایپ اسکریپت (Typescript) — از صفر تا صد
پیچیدگی نوع در تایپ اسکریپت
زمان استفاده از جاوا اسکریپت بهتر است دادهای را به نوع خاصی مرتبط نکنیم. ممکن است کاربر بخواهد در کدنویسی خود مشخص کند هر نوع داده پشتیبانی شود و اینجا جایی است که نوع خاص تایپ اسکریپت به نام any
وارد میدان میشود. با استفاده از این عنصر در کدنویسی تایپ اسکریپت میتوان مشخص کرد که هر دادهای میتواند با هر نوعی به کار رود. به عبارت دیگر وقتی any
به هر متغیری داده شود، یعنی هر مقداری میتواند در آن قرار بگیرد. any
در واقع به کامپایلر اعلام میکند که باید از تایپ ضعیف (تعیین نوع پویا) استفاده کند.
استفاده از any
زیاد توصیه نمیشود، چرا که مزایای تایپ اسکریپت را از کاربر میگیرد. مثال زیر در این رابطه مهم است.
let x: any = "Hello";
x = 1; // works as any can change type
این کار شبیه استفاده از تایپ (نوع) در سناریوهای دیگر مانند پارامترهای تابع است. زمانی که کاربر میخواهد انعطافپذیری زیادی را به کدنویسی خود از لحاظ تعیین نوع ببخشد، میتواند از any
استفاده کند. مثال زیر در این رابطه ارائه شده است.
function write(message: any) {
console.log(message);
}
write("Foo");
write(1);
write(true);
در مثال فوق، هر نوعی که ارسال شود به عنوانmessage
کار میکند اما در برخی موارد کاربر میخواهد انواع را محدود کند. برای مثال کاربر میخواهد نوع فقط با اعداد و رشته کار کند. در این رابطه کاربر ممکن است بخواهد تا نوع داده را با هر نوعی امتحان کند تا به این هدف برسد، اما برای سادگی کار میتواند از نوع «Union» یا نوع واحد استفاده کند. «Union» نوعی برای تطبیق الگوهای نوع و بررسی آنها است. در union
برای بررسی نوع، پارامترهای نوع توسط علامت «OR» یا « |
» از همدیگر جدا میشوند. در مثال زیر این موضوع به خوبی نشان داده شده است.
function write(message: string | number) {
console.log(message);
}
write("Foo");
write(1);
write(true); // fails
برخلاف سایر زبانهایی که از بررسی نوع ایستا پشتیبانی میکنند، تایپ اسکریپت به کاربر امکان میدهد انواع دادههایی را مشخص کند که ممکن است با محدودیتهای بررسی نوع ایستا ناسازگار باشند.
توابع در تایپ اسکریپت
از آنجایی که توابع بخش جداناپذیری از هر پروژه جاوا اسکریپت هستند، در نتیجه جای تعجبی ندارد که توابع جاوا اسکریپت شامل بررسی نوع نیز باشند.
در ادامه تابعی ساده از جاوا اسکریپت برای بررسی این موضوع ارائه شده است.
function formatName(firstName, lastName) {
if (!firstName || !lastName) return null;
return `${lastName}, ${firstName}`;
}
let fullName = formatName("Shawn", "Wildermuth");
اگر این تابع در تایپ اسکریپت تعریف شود، نتیجه این خواهد بود که firstName
و lastName
«شی» (Object) هستند و تابع رشتهای را بازمیگرداند. مثال زیر این موضوع را در تایپ اسکریپت نشان میدهد.
function formatName(firstName: string, lastName: string) {
if (!firstName || !lastName) return null;
return `${lastName}, ${firstName}`;
}
let fullName = formatName("Shawn", "Wildermuth");
این قطعه کد به کاربر کمک میکند رشتههایی را برای firstName
و lastName
ارسال کند، ولی نوع بازگشت در این قطعه کد مشخص نیست و باید به صورت زیر برای استنباط نوع بازگشت بهروزرسانی شود:
function formatName(firstName: string, lastName: string) : string {
if (!firstName || !lastName) return null;
return `${lastName}, ${firstName}`;
}
همچنین باید به این نکته توجه داشته باشیم که نوع بازگشت بعد از تابع و علامت دونقطه قرار میگیرد. در قطعه کد فوق این بازگشت موردنیاز نیست و خود استنتاج تایپ اسکریپت این موضوع را بیان میکند. برای این مثال کاربر میداند که نتیجه null
میشود و یا رشتهای را بازمیگرداند، بنابراین کاربر میتواند از نوع واحد یا union type
برای این هدف استفاده کند. مثال بالا با این اوصاف به صورت زیر بهروز میشود.
// Using an ellipse for consiseness
function formatName(...) : string | null {
البته شایانذکر است که تابع مدنظر در این مثال اگر چیزی را بازگرداند، بهعنوان نوع void
استنباط میشود و در این مورد نیز میتوان کاملاً صریح بود.
// Using an ellipse for conciseness
function formatName(...) : void {
استفاده از نوع یا تایپ برای پارامترهای مختلف و مقادیر بازگشتی باید به کاربر نشان دهد که آیا از توابع درستی استفاده میکند یا خیر. حال که در مورد این مسئله که رسالت توابع تایپ اسکریپت چیست سخن به میان آمد، در بخش بعد نوبت به بررسی تعریف نوع در تایپ اسکریپت خواهد رسید.
تعریف نوع در تایپ اسکریپت
ممکن است برای کاربر سؤال باشد که روش تعریف نوع در تایپ اسکریپت به چه صورت است؟ اولین راه برای این کار استفاده از کلمه کلیدی type
است که در آن میتوان نوع را با نام و تعاریف مورد انتظار ایجاد کرد.
برای مثال در ادامه نوع برای داده Person
به صورت زیر تعریف شده است.
type Person = {
firstName: string,
lastName: string,
age: number
};
زمانی که نوع تعریف شد، میتوان از آن برای تعیین نوع و تعریف متغیرها به صورت زیر استفاده کرد.
let people: Person[];
متغیر Person
افراد را به عنوان اعضای آرایهای از نوع Person
تعریف میکند، اما در اینجا متغیر مذکور فقط نوع را تعریف میکند و کاری به مقداردهی اولیه ندارد. برای مقداردهی اولیه آن باید به صورت زیر عمل کرد:
let people: Person[] = [];
همچنین از اعلان عمومی نیز میتوان برای این کار به صورت زیر استفاده کرد:
let people = new Array();
در هر کدام از موارد بالا کامپایلر تایپ اسکریپت، نوع را بررسی میکند و همچنین در کنار آن بررسی خواهد کرد که متغیر Person
به آرایهای اختصاص داده شده است.
// Fails as this shape isn't the same as Person
people.push({
fullName: "Shawn Wildermuth",
age: 53
});
// This Works
people.push({
firstName: "Shawn",
lastName: "Wildermuth",
age: 53
});
استفاده از «تعاریف نوع» (Type Definitions) شکل مورد نیاز عناصر یا نوع آنها را مشخص میکند. همچنین شایانذکر است که متغیر تا زمانی که با الگوی نوع مطابقت داشته باشد، میتوان از شی ناشناس نیز برای آن استفاده کرد.
انواع پیشرفته در TypeScript — با مثال های کاربردی
کلاس در تایپ اسکریپت
سؤال مهم دیگری که ممکن است ذهن کاربر را درگیر کند این است رسالت کلاس در تایپ اسکریپت چیست و تایپ اسکریپت با کلاس چگونه برخورد میکند.
در بیشتر زبانهای رایج و اصلی، برنامه نویسان عادت دارند از کلاس به عنوان بخش مرکزی الگوی توسعه خود استفاده کنند.
کلاسهای جاوا اسکریپت بخشی از جاوا اسکریپت مُدرن (ES6) هستند و در جاوا اسکریپت کلاسیک وجود ندارند همچنین برخلاف بسیاری از زبانهای رایج مانند سی شارپ، جاوا و غیره، کلاسها راهی برای بستهبندی کدها هستند و با این وجود در جاوا اسکریپت چندان ضروری و حیاتی نیستند. با این حال تایپ اسکریپت از تعاریف کلاس و بررسی نوع آنها پشتیبانی میکند. مثال زیر برای درک این موضوع بسیار مهم است:
class Person {
firstName: string;
lastName: string;
age: number;
write() {
console.log(this.firstName + " " + this.lastName);
}
}
let person = new Person();
person.firstName = "Shawn";
person.lastName = "Wildermuth";
person.write();
برخلاف تعریف نوع، کلاسها علاوه بر داده نوع زمان اجرا را نیز نشان میدهند. مثال زیر برای درک این موضوع آورده شده است:
let isPerson = person instanceof Person;
مانند بخشهای دیگر جاوا اسکریپت. تایپ اسکریپت به کاربر اجازه میدهد بررسی نوع را به صورت معمولی و قابلانتظار به کد اضافه کند. بسته به این که کاربر چه سطحی از کدهای جاوا اسکریپت را کامپایل میکند، این کار به عنوان نوعی کلاس جاوا اسکریپت یا نماد شی که در «ECMAScript 3» وجود دارد، قابل انجام است. به صورت کلی قابلیت تعریف کلاسها در تایپ اسکریپت به کاربر اجازه میدهد که از ویژگیهای جدید جاوا اسکریپت بدون توجه به نسخه مورد استفاده آن بهره ببرد.
همچنین کلاسها در تایپ اسکریپت مفهوم «سازنده» (Constructors) را معرفی میکنند. از سازنده برای تعیین پارامترهای مقداردهی اولیه به کلاسها استفاده میشود. برای مثال میتوان سازندهای را به کلاس person
به صورت زیر اضافه کرد:
class Person {
firstName: string;
lastName: string;
age: number;
constructor(firstName: string,
lastName: string,
age: number) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
write() {
console.log(this.firstName + " " + this.lastName);
}
}
سازنده تابعی به حساب میآید که پارامترهایی را میپذیرد و در عین حال میتواند برای نمونهسازی شی استفاده شود. در اینجا زمانی که کاربر میخواهد نمونهای را ایجاد کند و هنگامی که سازنده در حال تعیین الگوی مقداردهی اولیه است، خطای نوع اتفاق میافتد.
// Fails
let person = new Person();
// Succeeds
let person = new Person("...", "...", 53);
راه آسان و میانبر برای تعیین نوع این سازنده این است که شفافیت داشته باشد و در این صورت سازنده فیلدها را برای کاربر ایجاد میکند. قطعه کد زیر برای درک این مفهوم بسیار مهم است:
class Person {
// No longer necessary
// firstName: string;
// lastName: string;
// age: number;
constructor(public firstName: string,
public lastName: string,
public age: number) {
// this.firstName = firstName;
// this.lastName = lastName;
// this.age = age;
}
write() {
console.log(this.firstName + " " + this.lastName);
}
}
این کار به کاربر امکان میدهد که فیلدها را به صورت کوتاهتر از زمان مقداردهی اولیه مشخص کند و در این صورت میتوان مستقیماً متغیرها را به عنوان فیلد در معرض نمایش قرار دارد. علاوه بر این، تایپ اسکریپت از «سینتکس دسترسی» (Accessor Syntax) (مانند ویژگی کلاس در سایر زبانها) برای این هدف پشتیبانی میکند.
class Person {
constructor(public firstName: string,
public lastName: string,
public age: number) { }
get yearsSinceAdult() {
return this.age - 18;
}
set yearsSinceAdult(value: number) {
this.age = value + 18;
}
}
let person = new Person("..,", "...", 53);
const adulting = person.yearsSinceAdult; // 35
person.yearsSinceAdult = 25;
const age = person.age; // 43
این کار به کاربر اجازه میدهد که دسترسی به فیلد را مشخص کرده و در عین حال «گیرنده» (Getter) و «تنظیمکنندههای» (Setter) یک ویژگی را نیز رهگیری کند. تایپ اسکریپت از اصلاحکنندههای دیگری مانند protected
، private
، readonly
و غیره نیز پشتیبانی میکند که در این مقاله این موارد پوشش داده نمیشوند.
قابلیت های کمتر شناخته شده TypeScript — راهنمای کاربردی
وراثت در تایپ اسکریپت
یکی دیگر از جنبههای مختلف در مورد اینکه تایپ اسکریپت چیست و چه ویژگیهایی دارد، بحث «وراثت» (inheritance) یا ارثبری است. کلاسها در زبانهای برنامه نویسی شیگرا از مفهوم وراثت پشتیبانی میکنند ولی در جاوا اسکریپت و تایپ اسکریپت این مفهمم مبتنی بر کلاس نیست و مبتنی بر شی است، به این دلیل شیگرایی در تایپ اسکریپت مانند زبانهای برنامه نویسی دیگر نیست.
برای مثال اگر کاربر بخواهد از کلاسی پایه ارثبری کند باید نوع آن را با کلمه کلیدی extends
گسترش دهد. مثال زیر برای درک این موضوع بسیار مهم است.
class Manager extends Person {
reports: Person[];
}
در مثال فوق، کاربر نوع Person
را با نوع جدیدی به نام Manager
بسط میدهد، مگر اینکه کاربر سازنده خود را برای آن تعریف کند. در اینگونه موارد فقط میتوان از «سازنده کلاس سوپر» (Super-Class Constructor) استفاده کرد. با این شرایط، شی Manager
که تازه ایجاد شده، هم یک Manager
و هم یک Person
است. مثال زیر این مفهوم را نشان میدهد.
let mgr = new Manager("..,", "...", 53);
mgr.reports.push(person);
let isPerson = mgr instanceof Person; // true
let isManager = mgr instanceof Manager; //true
این کار به کاربران اجازه میدهد در صورت لزوم کلاسها را اختصاصی کرده یا آنها را به زیر کلاسها گسترش دهند. گاهی اوقات کاربر به ارثبری نیاز ندارد، اما در عوض میخواهد مشخص کند که شیئی به نوعی قرارداد (برای مثال رابطها) یا قانون پایبند است که برای این هدف باید نوعی «رابط» (Interface) ایجاد شود که دارای فیلدها، متدها و سایر موارد باشد. در مثال زیر نوعی رابط یا واسط برای شی Person
ایجاد شده است:
interface IPerson {
firstName: string;
lastName: string;
age: number;
}
در چنین مواردی، کلاس به جای اینکه نیازی به گسترش نوع داشته باشد، از طریق رابطی تضمین میکند که دارای اعضای خاصی است. میتوان با استفاده از کلمه کلیدی Implements
این کار را به صورت زیر انجام داد:
class Person implements IPerson {
اگر کلاس تعریف شده هیچ یک از عناصر رابط را نداشت، «خطای بررسی نوع» (Type Checking Error) اتفاق خواهد افتاد. کاربر میتواند بیش از یک رابط را برای این هدف پیادهسازی کند، اما نمیتواند بیش از یک سوپر کلاس را برای این هدف گسترش دهد. تا زمانی که شی به این دو قرارداد پایبند باشد، روش به کار گرفته شده قابل قبول خواهد بود:
class Person implements IPerson, IWriteable {
شاید این مسئله برای کاربر سؤال باشد که تفاوت میان رابط و نوع در تایپ اسکریپت چیست؟ این دو عنصر بسیار شبیه به هم هستند. میتوان از implements
برای تعریف نوع استفاده کرد. مثال زیر با هدف تفهیم این مسئله آورده شده است:
interface IPerson {
firstName: string;
lastName: string;
age: number;
}
type IWriteable = {
write() : void;
}
class Person implements IPerson, IWriteable {
تحلیل مثال بالا به عهده کاربر است و با درک آن خواهد توانست تفاوت نوع و رابط را به خوبی بفهمد.
شی گرایی در جاوا اسکریپت — به زبان ساده
پیکربندی کامپایلر تایپ اسکریپت
بدون فایل پیکربندی، تایپ اسکریپت از پیکربندیهای پیشفرض محافظهکارانه استفاده میکند و ممکن است خطاهایی مانند زیر در عین کامپایل به وجود آیند.
tsc index.ts index.ts:26:7 - error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. 26 get yearsSinceAdult() { ~~~~~~~~~~~~~~~ index.ts:30:7 - error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. 30 set yearsSinceAdult(value: number) { ~~~~~~~~~~~~~~~ Found 2 errors in the same file, starting at: index.ts:26
در مورد فوق، خطایی کدها اتفاق میافتد، زیرا کامپایلر تلاش میکند عملیات کامپایل را با قدیمیترین نسخه (به عنوان مثال، EcmaScript 3) انجام دهد؛ این باعث بروز خطای پیکربندی تایپ اسکریپت میشود. با استفاده از خود کامپایلر میتوان فایل پیکربندی پیشفرض جدیدی را ایجاد یا آن را به صورت زیر تغییر داد:
> tsc --init
با این کار فایلی به نام tsconfig.json
ایجاد میشود. نوع پیکربندی که با این کار به فایل پیکربندی اضافه میشود، تمام گزینههای موجود برای تنظیمات را نشان میدهد و میتواند کمی پیچیده باشد. برای این هدف میتوان فایل پیکربندی را به عنوان فایلی ساده نیز ایجاد کرد. برای مثال در اینجا با شیئی خالی و با ویژگی به نام include
این کار انجام خواهد شد:
{
"include": [ "index.ts" ]
}
همچنین میتوان کاراکترهای عام (کاراکترهای عام مانند کاراکتر *، #، ؟ و غیره) را نیز به صورت زیر مشخص کرد:
"include": [ "**/*.ts" ],
اگر کاربر از NPM استفاده کند، استفاده از کاراکترهای عام میتواند روند کار کاربر را با مشکل مواجه سازد و برای گذر از این چالش، باید دایرکتوری node_modules
به صورت زیر حذف شود:
{
"include": [ "**/*.ts" ],
"exclude": [ "node_modules/"],
}
اگر کامپایلر بدون آرگومان شروع به کار کند، خطاهای گذشته ممکن است با خطای فعلی یکسان باشند و دوباره اتفاق بیفتند، زیرا کاربر برای تایپ اسکریپت مشخص نکرده است که چگونه کدها را کامپایل کند. این کار با استفاده از شیئی به نام compilerOptions
قابل انجام است.
{
"include": [ "**/*.ts" ],
"exclude": [ "node_modules/"],
"compilerOptions": { }
}
بیشتر تنظیمات مربوط به پیکربندی فایل در compilerOptions
وجود دارد. برای مثال در ادامه برای رفع خطا به تایپ اسکریپت گفته میشود که چه نسخهای از جاوا اسکریپت را کامپایل کند. در پیکربندی پایین این تنظیمات برای نسخه «EcmaScript 2015» پیکربندی شده است که در بیشتر مرورگرها بدون مشکل اجرا میشود.
{
"include": ["**/*.ts"],
"exclude": ["node_modules/"],
"compilerOptions": {
"target": "ES2015"
}
}
حال اگر کامپایلر Tsc را اجرا کنیم، بدون هیچ مشکلی عملیات کامپایل اجرا خواهد شد. بدون ایجاد هیچگونه تغییری تایپ اسکریپت تا حدودی مجاز است هر گونه تبدیل نوعی را انجام دهد. اغلب برای کدهای بزرگ و پیچیده سختگیریهایی (حالت سخت) در مورد تایپ اجباری force typing
اعمال میشود.
{
"include": ["**/*.ts"],
"exclude": ["node_modules/"],
"compilerOptions": {
"target": "ES2015",
"strict": true
}
}
موارد بالا مبانی پیکربندی کامپایلر تایپ اسکریپت را به خوبی پوشش میدهند و با این حال گزینههای بسیار بیشتر و بهتری بسته به نیاز کاربر برای پیکربندی کامپایلر تایپ اسکریپت وجود دارد که کاربر میتوان آنها را روی فایل پیکربندی اعمال کند.
کتابخانه های تایپ اسکریپت
یکی دیگر از مزایای تایپ اسکریپت که ممکن است چندان قابلتوجه نباشد، به کارگیری عنصری به نام TypeScript در کدنویسی آن است. زمانی که از تایپ اسکریپت استفاده میشود کلاسها، توابع و انواع داده در پروژه بررسی نوع میشوند. اما این مسئله در مورد سایر فریمورکها یا کتابخانههایی که استفاده خواهند شد چطور است؟
ممکن است کاربری در پروژههایی که کار میکند نیاز به NPM داشته باشد که احتمال دارد از چندین کتابخانه برای این هدف استفاده کند. برای مثال کتابخانه «Moment*» به این صورت به پروژه اضافه میشود:
> npm install moment
نکته: استفاده از Moment* فقط به عنوان مثال ذکر شده و ممکن است کاربر از کتابخانههای مختلفی استفاده کند.
سؤال اصلی اینجاست که در هنگام استفاده از کتابخانهها کمک اصلی تایپ اسکریپت چیست و چگونه این فرایند را بهبود میبخشد؟ بسیاری از کتابخانههای جاوا اسکریپت اطلاعات نوع را در قالب کتابخانههای نوع (معمولاً {projectName}.g.ts
) به پروژه اضافه میکنند. مثلاً در کتابخانه Moment* از moment.g.ts
استفاده خواهد شد. این یعنی زمانی که از کتابخانه moment* در پروژه استفاده میشود، جاوا اسکریپت و تایپ اسکریپت از رابط و انواع این کتابخانه مطلع میشوند.
بیشتر ویرایشگرهای موجود مانند ویژوال استودیو، ویژوال استودیو کد و غیره این نوع کتابخانهها را پشتیبانی میکنند و از آن برای کمک به «IntelliSense» و فرایند کامپایل استفاده خواهند کرد.
آموزش Visual Studio Code — از نصب تا اجرای اولین پروژه در VS Code
کامپایلر تایپ اسکریپت از این اطلاعات نوع برای تائید درستی کد استفاده میکند. برای مثال اگر کاربر بخواهد تاریخ را در لحظه با استفاده از کتابخانه Moment* تجزیه کند، فرایند به صورت زیر خواهد بود:
let date = moment("2025-05-05");
در قطعه کد بالا به نظر میرسد از جاوا اسکریپت استفاده شده است، اما با این حال، اطلاعات نوع در آن وجود دارد و استنباط میشود:
let date: moment.Moment = moment("2025-05-05");
این قطعه کد همان چیزی است که اصل صریح بودن در اطلاعات نوع را بیان میکند. این یعنی در تایپ اسکریپت حتی اگر از بررسی نوع هم استفاده نشود، وجود «کتابخانههای نوع» (Type Libraries) مزایای زیادی در توسعه وب به همراه دارد.
سؤالات متداول پیرامون زبان تایپ اسکریپت
در این بخش چند سؤال متداول پیرامون این موضوع که تایپ اسکریپت چیست و چه ویژگیهایی دارد ارائه شده است.
تفاوت جاوا اسکریپت و تایپ اسکریپت چیست؟
جاوا اسکریپت نوعی زبان برنامه نویسی است که در درجه اول برای ایجاد صفحات وب پویا استفاده میشود. جاوا اسکریپت نوعی زبان مفسری به حساب میآید و میتواند در سمت مشتری و همچنین سمت سرور استفاده شود، از طرفی تایپ اسکریپت یک ابَرمجموعه یا فوق مجموعه از جاوا اسکریپت به حساب میآید و زبانی کامپایلری محسوب میشود و میتوان از آن برای ایجاد برنامههایی استفاده کرد که در سمت سرور اجرا میشوند.
نکات و ترفندهای تایپ اسکریپت — راهنمای کاربردی
هدف از توسعه Typescript چیست؟
تایپ اسکریپت طراحی شده است تا نوشتن و نگهداری برنامههای بزرگ و پیچیده را آسانتر کند. تایپ اسکریپت در واقع ویژگیهای تعیین نوع ایستا یا تایپ قوی مانند کلاسها، رابطها، حاشیهنویسیهای نوع و ماژولها را فراهم میکند که دیباگ کردن، اصلاح و نگهداری کدها را آسانتر کند. تایپ اسکریپت همچنین میتواند برای ایجاد برنامههای وب و موبایل استفاده شود.
معایب تایپ اسکریپت چیست؟
تایپ اسکریپت نسبتاً جدید است و از برخی ابزارها و کتابخانهها پشتیبانی نمیکند و یادگیری و درک آن به زمان زیادی نیاز دارد. همچنین تایپ اسکریپت از همه مرورگرها پشتیبانی نمیکند و برای اجرا به یک مرحله کامپایل نیاز دارد که این به خودی خود به پیچیدگی آن اضافه میکند. از طرف دیگر، اشکالزدایی و دیباگ کدهای تایپ اسکریپت کمی دشوار است.
سخن پایانی
تایپ اسکریپت زبان مهمی است که به کاربر امکان میدهد کیفیت کدهای خود را در پروژههای بزرگ بهبود ببخشد. در این مطلب آموزشی از مجله تم آف در رابطه با اینکه تایپ اسکریپت چیست، چه ویژگیها و چه مزایای دارد و بسیاری از موارد دیگر اطلاعاتی جامع و کاربردی ارائه شد که این اطلاعات به کاربر کمک میکنند تا درک روشنی از تایپ اسکریپت و تفاوت آن با جاوا اسکریپت داشته باشد.