قابلیت های جدید و جالب تایپ اسکریپت ۳.۶ — راهنمای کاربردی
با معرفی تایپ اسکریپت نسخه 3.6 قابلیتهای زیادی به آن اضافه شده است. از جمله، ویژگیهایی برای عناصر تکرارپذیر مانند بررسی نوع صریحتر برای generator-ها، گسترش دقیقتر آرایه، استفاده از get و set در گزارههای declare و مواردی از این دست است. در این مقاله به بررسی برخی از قابلیت های جدید و جالب تایپ اسکریپت 3.6 میپردازیم.
بررسی نوع صریحتر برای generator-ها
با معرفی نسخه 3.6 تایپ اسکریپت، اینک کامپایلر این زبان بررسیهای بیشتری برای انواع داده در generator-ها دارد.
اکنون روشی برای تمایز بین این کد از یک generator ،yield یا return میشود در دست داریم، برای نمونه در generator زیر:
1function* bar() {
2 yield 1;
3 yield 2;
4 return "Finished!"
5}
6let iterator = bar();
7let curr = iterator.next();
8curr = iterator.next();
9if (curr.done) {
10 curr.value
11}
کامپایلر نسخه 3.6 به طور خودکار میداند که curr.value یک رشته است، چون در پایان تابع یک رشته بازگشت یافته است. ضمناً yeald زمانی که به چیزی انتساب یابد از نوع any تلقی نمیشود. برای نمونه کد زیر را داریم:
1function* bar() {
2 let x: { foo(): void } = yield;
3}
4let iterator = bar();
5iterator.next();
6iterator.next(123);
اکنون کامپایلر تایپ اسکریپت میداند که 123 قابلیت انتساب به چیزی با نوع { foo(): void } ندارد، چون از نوع x است. در حالی که در نسخههای قبلی کامپایلر در کد فوق این بررسی نوع را انجام نمیداد. بنابراین در تایپ اسکریپت 3.6 به بالا خطای زیر را دریافت میکنیم:
1Argument of type '[123]' is not assignable to parameter of type '[] | [{ foo(): void; }]'.
2Type '[123]' is not assignable to type '[{ foo(): void; }]'.
3Type '123' is not assignable to type '{ foo(): void; }'.
همچنین تعاریف نوع را برای Generator داریم و Iterator دارای متدهای return و throw است. تایپ اسکریپت 3.6 اقدام به تبدیل IteratorResult به نوع یونیون <IteratorYieldResult<T> | IteratorReturnResult<TReturn میکند.
همچنین میتواند مقداری که از ()next را از آنچه فراخوانی شده، استنباط کند. برای مثال کد زیر کامپایل و اجرا میشود، زیرا نوع صحیح مقدار به ()next ارسال شده است که یک رشته است:
1function* bar() {
2 let x: string = yield;
3 console.log(x.toUpperCase());
4}
5let x = bar();
6x.next();
7x.next('foo');
با این حال کد زیر نمیتواند کامپایل شود، زیرا نوع آرگومان و نوع x مطابقت ندارند:
1function* bar() {
2 let x: string = yield;
3 console.log(x.toUpperCase());
4}
5let x = bar();
6x.next();
7x.next(42);
باید یک رشته ارسال کنیم تا خطایی که از ;x.next(42) ناشی میشود را اصلاح کنیم. ضمناً کامپایلر تایپ اسکریپت میداند که فراخوانی اول به ()next کاری انجام نمیدهد.
گسترش دقیقتر آرایهها
در نسخه 3.6 تایپ اسکریپت، برخی عملگرهای اسپرد نوعی تغییر یافتهاند که نتایج یکسانی در زمان transpile شدن کد به ES5 یا نسخههای قبلتر با استفاده از فلگ downlevelIteration- به دست میدهند. هدف از این فلگ آن است که سازههای ES6 مانند عملگر spread و حلقههای for…of را به چیزی تبدیل کنیم که کدهای قدیمی هم بتوانند مورد استفاده قرار دهند. برای نمونه اگر کدی مانند زیر داشته باشیم:
[...Array(3)]
نتیجه زیر به دست میآید:
[undefined, undefined, undefined]
با این حال، نسخههای تایپ اسکریپت قبل از 3.6 سازه [Array(3)…] را به ;()Array(3).slice تبدیل میکردند، که یک آرایه خالی با مشخصه length 3 به دست میداد.
صدور خطا در مورد کدهای Promise بد
کامپایلر تایپ اسکریپت 3.6 به ما امکان میدهد بدانیم آیا فراموش کردهایم قبل از promise-ها در تابع async یک await بگذاریم و آیا فراخوانی به then را پس از promise فراموش کردهایم یا نه. برای نمونه اگر کدی مانند زیر داشته باشیم:
1interface Person {
2 name: string;
3}
4let promise: Promise<Person> = Promise.resolve(<Person>{ name: 'Joe' });
5(async () => {
6 const person: Person = promise;
7})();
در این صورت خطای زیر رخ میدهد:
Property 'name' is missing in type 'Promise<Person>' but required in type 'Person'.
قرار دادن یک await پیش از promise میتواند این مشکل را حل کند:
1interface Person {
2 name: string;
3}
4let promise: Promise<Person> = Promise.resolve(<Person>{ name: 'Joe' });
5(async () => {
6 const person: Person = await promise;
7})();
به این ترتیب کدی مانند زیر:
1(async () => {
2 fetch("https://reddit.com/r/javascript.json")
3 .json()
4})();
خطای زیر را ایجاد میکند:
1Property 'json' does not exist on type 'Promise<Response>'.(2339)
2input.ts(3, 10): Did you forget to use 'await'?
اما کد زیر خطا را اصلاح میکند:
1(async () => {
2 const response = await fetch("https://reddit.com/r/javascript.json")
3 const responseJson = response.json()
4})();
شناسههای کاراکتر یونیکد
اکنون میتوانیم از کاراکترهای یونیکد برای شناسهها در تایپ اسکریپت استفاده کنیم. برای نمونه دستور زیر در کامپایلرهای تایپ اسکریپت 3.6 به بعد کار میکند:
1const ? = 'foo';
اکسسورهای get و set در گزارههای اعلان مجاز هستند
اینک میتوانیم get و set را به گزارههای declare اضافه کنیم. برای نمونه میتوانیم کدی مانند زیر بنویسیم:
1declare class Bar {
2 get y(): number;
3 set y(val: number);
4}
تعاریف نوع تولیدشده نیز اکسسورهای get و set را در تایپ اسکریپت 3.8 و بالاتر عرضه خواهند کرد.
ادغام گزارههای اعلان تابع سازنده و کلاس
از نسخه 3.6 تایپ اسکریپت به بعد کامپایلر این هوشمندی را یافته است تا گزارههای declare کلاس و سازندههای تابع را که نام یکسانی دارند با هم ادغام کند. برای نمونه اکنون میتوانیم کدی مانند زیر بنویسیم:
1export declare function Person(name: string, age: number): Person;
2export declare class Person {
3 name: string;
4 age: number;
5 constructor(name: string, age: number);
6}
کامپایلر میداند که تابع یک سازنده است و کلاس نیز همانند تابع است. امضای سازندهها در تابع و سازنده کلاس لازم نیست با هم منطبق باشد، بنابراین کد زیر نیز صحیح است:
1export declare function Person(name: string): Person;
2export declare class Person {
3 name: string;
4 age: number;
5 constructor(name: string, age: number);
6}
نقطه ویرگول
اکنون تایپ اسکریپت به قدر کافی هوشمند است تا نقطهویرگول را به صورت خودکار به مکانهایی که بر اساس سنتهای استایل کدنویسی لازم هستند و نه همه مکانها اضافه کند.
سخن پایانی
تایپ اسکریپت 3.6 یک نسخه با امکانات متعدد است. عمده تمرکز این نسخه روی بهبود مواردی مانند استنباط نوع و بررسی نوع در generator-ها، گسترش دقیقتر آرایهها برای کدهای ناموجود در ES5 و قبلتر بوده است. همچنین کدهای بد promise مانند فراموش کردن دستورهای await و then که موجب بروز خطا میشوند نیز اصلاح میشوند. ادغام کد سازنده تابع و کلاس در گزارههای declare نیز هماینک پشتیبانی میشود. همچنین کاراکترهای یونیکد را میتوان در شناسهها وارد کرد و نقطهویرگول هم به دیگر صورت خودکار به همه خطوط اضافه نمیشود.
اگر این مطلب برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای برنامهنویسی JavaScript (جاوا اسکریپت)
- مجموعه آموزشهای برنامهنویسی
- مفهوم تابع در تایپ اسکریپت — به زبان ساده
- راهنمای جامع تایپ اسکریپت (Typescript) — از صفر تا صد
- درک انواع در تایپ اسکریپت — به زبان ساده
==
« گزارههای declear و مواردی …»
غلط املایی. declare درسته.
ممنون از مطالب خوبتون.
با سلام و احترام؛
صمیمانه از همراهی شما با مجله فرادرس و ارائه بازخورد سپاسگزاریم.
این مورد اصلاح شد.
برای شما آرزوی سلامتی و موفقیت داریم.