موارد جدید در TypeScript 5.0: Declarators، Const Type، Enums Improvement، Speed، Bundler Resolution


TypeScript 5.0 به طور رسمی در 16 مارس 2023 منتشر شد و اکنون برای استفاده در دسترس همه است. این نسخه بسیاری از ویژگی های جدید را با هدف کوچکتر، ساده تر و سریعتر کردن TypeScript معرفی می کند.

این نسخه جدید دکوراتورها را برای سفارشی‌سازی کلاس مدرن می‌کند و امکان سفارشی‌سازی کلاس‌ها و اعضای آن‌ها را به روشی قابل استفاده مجدد فراهم می‌کند. توسعه‌دهندگان اکنون می‌توانند یک اصلاح‌کننده const را به یک اعلان پارامتر نوع اضافه کنند و به استنتاج‌های const اجازه دهند پیش‌فرض باشند. نسخه جدید همچنین تمام enums را به صورت union enum می کند، ساختار کد را ساده می کند و تجربه TypeScript را سرعت می بخشد.

در این مقاله، تغییرات ایجاد شده در TypeScript 5.0 را بررسی می کنید و نگاهی عمیق به ویژگی ها و قابلیت های جدید آن ارائه می دهید.

شروع کار با TypeScript 5.0

TypeScript یک کامپایلر رسمی است که می توانید با استفاده از npm در پروژه خود نصب کنید. اگر می خواهید از TypeScript 5.0 در پروژه خود استفاده کنید، می توانید دستور زیر را در پوشه پروژه خود اجرا کنید:

npm install -D typescript

با این کار کامپایلر در node_modules دایرکتوری که اکنون می توانید با آن اجرا کنید npx tsc فرمان

همچنین می توانید دستورالعمل های استفاده از نسخه جدیدتر TypeScript در Visual Studio Code را در این مستندات بیابید.

ICYMI: TypeScript 5.0 اینجاست! به روز رسانی های هیجان انگیز آن مانند Declarators، Const Type و Enums بهبود یافته را در این راهنما کاوش کنید✅برای توییت کلیک کنید

چه چیزی در TypeScript 5.0 جدید است؟

در این مقاله، اجازه دهید 5 به روز رسانی اصلی معرفی شده در TypeScript را بررسی کنیم. این ویژگی ها عبارتند از:

دکوراتورهای مدرن

دکوراتورها برای مدتی تحت یک پرچم آزمایشی در تایپ اسکریپت حضور داشتند، اما نسخه جدید آنها را با پیشنهاد ECMAScript که اکنون در مرحله 3 است، سرعت می بخشد، به این معنی که در مرحله ای است که به TypeScript اضافه می شود.

دکوراتورها راهی برای سفارشی کردن رفتار کلاس ها و اعضای آنها به روشی قابل استفاده مجدد هستند. برای مثال، اگر کلاسی دارید که دو متد دارد، greet و getAge:

class Person {
    name: string;
    age: number;
    constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
    }

    greet() {
        console.log(`Hello, my name is ${this.name}.`);
    }

    getAge() {
        console.log(`I am ${this.age} years old.`);
    }
}

const p = new Person('Ron', 30);
p.greet();
p.getAge();

در موارد استفاده در دنیای واقعی، این کلاس باید روش‌های پیچیده‌تری داشته باشد که برخی از منطق ناهمگام را مدیریت می‌کند و دارای عوارض جانبی و غیره است، جایی که می‌خواهید برخی از آنها را وارد کنید. console.log برای کمک به اشکال زدایی روش ها تماس می گیرد.

class Person {
    name: string;
    age: number;
    constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
    }

    greet() {
        console.log('LOG: Method Execution Starts.');
        console.log(`Hello, my name is ${this.name}.`);
        console.log('LOG: Method Execution Ends.');
    }

    getAge() {
        console.log('LOG: Method Execution Starts.');
        console.log(`I am ${this.age} years old.`);
        console.log('Method Execution Ends.');
    }
}

const p = new Person('Ron', 30);
p.greet();
p.getAge();

این یک الگوی است که اغلب اتفاق می افتد، و داشتن راه حلی برای اعمال در هر روشی راحت است.

اینجاست که دکوراتورها وارد بازی می شوند. ما می توانیم یک تابع به نام تعریف کنیم debugMethod که به صورت زیر ظاهر می شود:

function debugMethod(originalMethod: any, context: any) {
    function replacementMethod(this: any, ...args: any[]) {
        console.log('Method Execution Starts.');
        const result = originalMethod.call(this, ...args);
        console.log('Method Execution Ends.');
        return result;
    }
    return replacementMethod;
}

در کد بالا، debugMethod روش اصلی را می گیرد (originalMethod) و تابعی را برمی گرداند که کارهای زیر را انجام می دهد:

  1. پیامی را ثبت می‌کند که “اجرای روش شروع می‌شود.”
  2. متد اصلی و تمام آرگومان های آن (از جمله این) را پاس می کند.
  3. یک پیغام «اجرای روش به پایان می رسد» ثبت می کند.
  4. هر آنچه را که روش اصلی برگردانده است برمی گرداند.

با استفاده از دکوراتورها می توانید از آن استفاده کنید debugMethod به روش های خود همانطور که در کد زیر نشان داده شده است:

class Person {
    name: string;
    age: number;
    constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
    }
    @debugMethod
    greet() {
        console.log(`Hello, my name is ${this.name}.`);
    }
    @debugMethod
    getAge() {
        console.log(`I am ${this.age} years old.`);
    }
}
const p = new Person('Ron', 30);
p.greet();
p.getAge();

این خروجی زیر را خواهد داشت:

LOG: Entering method.
Hello, my name is Ron.
LOG: Exiting method.
LOG: Entering method.
I am 30 years old.
LOG: Exiting method.

هنگام تعریف عملکرد دکوراتور (debugMethod، پارامتر دومی فراخوانی می شود context (این شیء متن است – اطلاعات مفیدی در مورد نحوه اعلان متد تزئین شده و همچنین نام متد دارد). شما می توانید خود را به روز کنید debugMethod برای دریافت نام روش از context هدف – شی:

function debugMethod(
    originalMethod: any,
    context: ClassMethodDecoratorContext
) {
    const methodName = String(context.name);
    function replacementMethod(this: any, ...args: any[]) {
        console.log(`'${methodName}' Execution Starts.`);
        const result = originalMethod.call(this, ...args);
        console.log(`'${methodName}' Execution Ends.`);
        return result;
    }
    return replacementMethod;
}

هنگامی که کد خود را اجرا می کنید، خروجی اکنون نام هر روشی را که با آن تزئین شده است، خواهد داشت debugMethod دکوراتور:

'greet' Execution Starts.
Hello, my name is Ron.
'greet' Execution Ends.
'getAge' Execution Starts.
I am 30 years old.
'getAge' Execution Ends.

کارهای بیشتری می توانید با دکوراتورها انجام دهید. برای اطلاعات بیشتر در مورد نحوه استفاده از دکوراتورها در TypeScript، می توانید درخواست اصلی کشش را بررسی کنید.

معرفی پارامترهای نوع const

این یک نسخه بزرگ دیگر است که ابزار جدیدی با ژنریک به شما می دهد تا استنتاجی را که هنگام فراخوانی توابع به دست می آورید، بهبود بخشد. به طور پیش فرض، زمانی که مقادیر را با const، TypeScript نوع را استنتاج می کند و نه مقادیر تحت اللفظی آن:

// Inferred type: string[]
const names = ['John', 'Jake', 'Jack'];

تا به حال، برای دستیابی به استنتاج مورد نظر، باید از ادعای const با اضافه کردن “as const” استفاده می‌کردید:

// Inferred type: readonly ["John", "Jake", "Jack"]
const names = ['John', 'Jake', 'Jack'] as const;

وقتی توابع را فراخوانی می کنید، مشابه است. در کد زیر، نوع استنباط شده از کشورها است string[]:

type HasCountries = { countries: readonly string[] };
function getCountriesExactly(arg: T): T['countries'] {
    return arg.countries;
}

// Inferred type: string[]
const countries = getCountriesExactly({ countries: ['USA', 'Canada', 'India'] });

ممکن است نوع خاصی از آن را بخواهید که یکی از راه‌های رفع آن قبلاً اضافه کردن آن بوده است as const ادعا:

// Inferred type: readonly ["USA", "Canada", "India"]
const names = getNamesExactly({ countries: ['USA', 'Canada', 'India'] } as const);

به خاطر سپردن و اجرای آن می تواند دشوار باشد. با این حال، TypeScript 5.0 یک ویژگی جدید را معرفی می‌کند که در آن می‌توانید یک اصلاح‌کننده const را به یک اعلان پارامتر نوع اضافه کنید، که به طور خودکار یک استنتاج مشابه const را به عنوان پیش‌فرض اعمال می‌کند.

type HasCountries = { countries: readonly string[] };
function getNamesExactly(arg: T): T['countries'] {
    return arg.countries;
}

// Inferred type: readonly ["USA", "Canada", "India"]
const names = getNamesExactly({ countries: ['USA', 'Canada', 'India'] });

استفاده كردن const پارامترهای نوع به توسعه دهندگان این امکان را می دهد تا هدف خود را با وضوح بیشتری در کد خود بیان کنند. اگر قرار است متغیری ثابت باشد و هرگز تغییر نکند، از a استفاده کنید const پارامتر نوع تضمین می کند که هرگز نمی توان آن را به طور تصادفی تغییر داد.

برای اطلاعات بیشتر در مورد نحوه عملکرد پارامتر نوع const در TypeScript، می توانید درخواست اصلی کشش را بررسی کنید.

بهبود Enums

Enums در TypeScript یک ساختار قدرتمند است که به توسعه دهندگان اجازه می دهد مجموعه ای از ثابت های نامگذاری شده را تعریف کنند. در TypeScript 5.0، بهبودهایی در enum ها انجام شده است تا آنها را حتی انعطاف پذیرتر و مفیدتر کند.

به عنوان مثال، اگر enum زیر را به یک تابع منتقل کنید:

enum Color {
    Red,
    Green,
    Blue,
}

function getColorName(colorLevel: Color) {
    return colorLevel;
}

console.log(getColorName(1));

قبل از معرفی TypeScript 5.0، می‌توانید یک عدد سطح اشتباه را ارسال کنید و هیچ خطایی ایجاد نمی‌کند. اما با معرفی TypeScript 5.0 بلافاصله خطا می دهد.

همچنین، نسخه جدید با ایجاد یک نوع منحصر به فرد برای هر عضو محاسبه شده، همه enum ها را به enums اتحادیه تبدیل می کند. این بهبود امکان محدود کردن همه فهرست‌ها و ارجاع اعضای آن‌ها به عنوان انواع را فراهم می‌کند:

enum Color {
    Red,
    Purple,
    Orange,
    Green,
    Blue,
    Black,
    White,
}

type PrimaryColor = Color.Red | Color.Green | Color.Blue;

function isPrimaryColor(c: Color): c is PrimaryColor {
    return c === Color.Red || c === Color.Green || c === Color.Blue;
}

console.log(isPrimaryColor(Color.White)); // Outputs: false
console.log(isPrimaryColor(Color.Red)); // Outputs: true

بهبود عملکرد TypeScript 5.0

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

به عنوان مثال، تفاوت بین اندازه بسته TypeScript 5.0 و 4.9 بسیار چشمگیر است.

TypeScript اخیراً از فضاهای نام به ماژول ها منتقل شده است و به آن امکان می دهد از ابزارهای ساخت مدرن استفاده کند که می تواند بهینه سازی هایی مانند بالا بردن محدوده را انجام دهد. همچنین، با حذف برخی از کدهای منسوخ، حدود 26.4 مگابایت از اندازه بسته 63.8 مگابایتی TypeScript 4.9 حذف شده است.

اندازه بسته TypeScript
اندازه بسته TypeScript

در اینجا چند برد جالب دیگر در سرعت و اندازه بین TypeScript 5.0 و 4.9 آورده شده است:

سناریو زمان یا اندازه نسبت به TS 4.9
زمان ساخت متریال رابط کاربری 90%
زمان راه اندازی کامپایلر TypeScript 89%
زمان ساخت نمایشنامه نویس 88%
زمان خود ساخت کامپایلر TypeScript 87%
زمان ساخت Outlook Web 82%
زمان ساخت کد VS 80%
تایپ npm اندازه بسته 59%

وضوح باندلر برای وضوح بهتر ماژول

وقتی یک دستور import را در TypeScript می نویسید، کامپایلر باید بداند واردات به چه چیزی اشاره دارد. این کار را با استفاده از وضوح ماژول انجام می دهد. مثلا وقتی می نویسی import { a } from "moduleA"، کامپایلر باید تعریف آن را بداند a که در moduleA برای بررسی استفاده از آن

در TypeScript 4.7، دو گزینه جدید برای آن اضافه شد --module و moduleResolution تنظیمات: node16 و nodenext.

هدف این گزینه ها نمایش دقیق تر قوانین جستجوی دقیق برای ماژول های ECMAScript در Node.js بود. با این حال، این حالت دارای چندین محدودیت است که توسط ابزارهای دیگر اعمال نمی شود.

به عنوان مثال، در یک ماژول ECMAScript در Node.js، هر واردات نسبی باید شامل یک پسوند فایل باشد تا به درستی کار کند:

import * as utils from "./utils"; // Wrong 

import * as utils from "./utils.mjs"; // Correct

TypeScript استراتژی جدیدی به نام “moduleResolution bundler” معرفی کرده است. این استراتژی را می توان با افزودن کد زیر در بخش “compilerOptions” فایل پیکربندی TypeScript خود پیاده سازی کرد:

{
    "compilerOptions": {
        "target": "esnext",
        "moduleResolution": "bundler"
    }
}

این استراتژی جدید برای کسانی که از باندلرهای مدرن مانند Vite، esbuild، swc، Webpack، Parcel و سایرین استفاده می کنند که از استراتژی جستجوی ترکیبی استفاده می کنند، مناسب است.

برای اطلاعات بیشتر در مورد چگونگی، می توانید درخواست اصلی کشش و اجرای آن را بررسی کنید moduleResolution باندلر در TypeScript کار می کند.

تحقیرها

TypeScript 5.0 با مقداری استهلاک همراه است، از جمله الزامات زمان اجرا، تغییرات lib.d.ts و تغییرات شکستن API.

  1. الزامات زمان اجرا: TypeScript اکنون ECMAScript 2018 را هدف قرار می دهد و بسته حداقل انتظار موتور را 12.20 تعیین می کند. بنابراین، کاربران Node.js باید حداقل نسخه 12.20 یا بالاتر را برای استفاده از TypeScript 5.0 داشته باشند.
  2. تغییرات lib.d.ts: تغییراتی در نحوه تولید انواع DOM ایجاد شده است که ممکن است بر کد موجود تأثیر بگذارد. به طور خاص، ویژگی‌های خاصی از انواع عددی به انواع تحت اللفظی عددی تبدیل شده‌اند، و ویژگی‌ها و روش‌های مربوط به برش، کپی و پیست کردن رویدادها در میان واسط‌ها منتقل شده‌اند.
  3. تغییرات شکستن API: برخی از رابط های غیر ضروری حذف شده اند و برخی بهبودهای صحت انجام شده است. TypeScript 5.0 نیز به ماژول ها منتقل شده است.

TypeScript 5.0 برخی از تنظیمات و مقادیر مربوط به آنها را منسوخ کرده است target: ES3، out، noImplicitUseStrict، keyofStringsOnly، suppressExcessPropertyErrors، suppressImplicitAnyIndexErrors، noStrictGenericChecks، charset، importsNotUsedAsValues، و preserveValueImportsو همچنین در منابع پروژه اضافه شود.

در حالی که این تنظیمات تا TypeScript 5.5 معتبر خواهند بود، هشداری برای هشدار به کاربرانی که هنوز از آنها استفاده می کنند صادر می شود.

TypeScript 5.0 ساده تر، سریعتر و کوچکتر است! تغییراتی را که در بازی کد نویسی شما متحول می شود را در اینجا کاوش کنید. ⚡️👇برای توییت کلیک کنید

خلاصه

در این مقاله، برخی از ویژگی‌ها و پیشرفت‌های عمده‌ای که TypeScript 5.0 به ارمغان می‌آورد، مانند بهبودهایی در enums، وضوح باندلر و پارامترهای نوع const، همراه با بهبود سرعت و اندازه را آموخته‌اید.

اگر برای پروژه های بعدی خود به TypeScript فکر می کنید، میزبانی برنامه Kinsta را به صورت رایگان امتحان کنید.

حالا نوبت شماست! چه ویژگی‌ها یا بهبودهایی را در TypeScript 5.0 جذاب‌تر می‌دانید؟ آیا موارد قابل توجهی وجود دارد که ممکن است نادیده گرفته باشیم؟ در نظرات به ما اطلاع دهید.


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

  • راه اندازی و مدیریت آسان در داشبورد MyKinsta
  • پشتیبانی تخصصی 24 ساعته
  • بهترین سخت افزار و شبکه Google Cloud Platform که توسط Kubernetes برای حداکثر مقیاس پذیری ارائه شده است
  • یک ادغام Cloudflare در سطح سازمانی برای سرعت و امنیت
  • مخاطبان جهانی با حداکثر 35 مرکز داده و 275 PoP در سراسر جهان به دست می‌آیند

با یک آزمایش رایگان میزبانی برنامه یا میزبانی پایگاه داده ما شروع کنید. برنامه های ما را بررسی کنید یا با فروشندگان صحبت کنید تا بهترین مناسب خود را پیدا کنید.