فارسی

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

انواع لیترال قالب تایپ‌اسکریپت برای APIهای امن از نظر نوع

انواع لیترال قالب (Template Literal Types) در تایپ‌اسکریپت یک ویژگی قدرتمند است که در نسخه ۴.۱ معرفی شد و به شما امکان می‌دهد تا دستکاری رشته‌ها را در سطح نوع انجام دهید. این ویژگی دنیایی از امکانات را برای ایجاد APIهای بسیار امن و قابل نگهداری باز می‌کند و به شما اجازه می‌دهد تا خطاهایی را در زمان کامپایل شناسایی کنید که در غیر این صورت فقط در زمان اجرا ظاهر می‌شدند. این امر به نوبه خود منجر به بهبود تجربه توسعه‌دهنده، بازسازی کد آسان‌تر و کدی قوی‌تر می‌شود.

انواع لیترال قالب چه هستند؟

در هسته خود، انواع لیترال قالب، انواع لیترال رشته‌ای هستند که می‌توانند با ترکیب انواع لیترال رشته‌ای، انواع اجتماع (union types) و متغیرهای نوع ساخته شوند. به آنها مانند درون‌یابی رشته (string interpolation) برای انواع فکر کنید. این به شما امکان می‌دهد تا انواع جدیدی را بر اساس انواع موجود ایجاد کنید و درجه بالایی از انعطاف‌پذیری و بیانگری را فراهم می‌کند.

در اینجا یک مثال ساده آورده شده است:

type Greeting = "Hello, World!";

type PersonalizedGreeting<T extends string> = `Hello, ${T}!`;

type MyGreeting = PersonalizedGreeting<"Alice">; // type MyGreeting = "Hello, Alice!"

در این مثال، PersonalizedGreeting یک نوع لیترال قالب است که یک پارامتر نوع عمومی T را می‌گیرد که باید یک رشته باشد. سپس یک نوع جدید با درون‌یابی لیترال رشته‌ای ",Hello " با مقدار T و لیترال رشته‌ای "!" می‌سازد. نوع حاصل، MyGreeting، برابر با "!Hello, Alice" است.

مزایای استفاده از انواع لیترال قالب

موارد استفاده در دنیای واقعی

۱. تعریف Endpointهای API

از انواع لیترال قالب می‌توان برای تعریف انواع endpointهای API استفاده کرد تا اطمینان حاصل شود که پارامترهای صحیح به API ارسال شده و پاسخ به درستی مدیریت می‌شود. یک پلتفرم تجارت الکترونیک را در نظر بگیرید که از چندین ارز مانند USD، EUR و JPY پشتیبانی می‌کند.

type Currency = "USD" | "EUR" | "JPY";
type ProductID = string; //در عمل، این می‌تواند یک نوع خاص‌تر باشد

type GetProductEndpoint<C extends Currency> = `/products/${ProductID}/${C}`;

type USDEndpoint = GetProductEndpoint<"USD">; // type USDEndpoint = "/products/${string}/USD"

این مثال یک نوع GetProductEndpoint را تعریف می‌کند که یک ارز را به عنوان پارامتر نوع می‌گیرد. نوع حاصل یک نوع لیترال رشته‌ای است که endpoint API را برای بازیابی یک محصول با ارز مشخص شده نشان می‌دهد. با استفاده از این رویکرد، می‌توانید اطمینان حاصل کنید که endpoint API همیشه به درستی ساخته شده و از ارز صحیح استفاده می‌شود.

۲. اعتبارسنجی داده‌ها

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

type CountryCode = "+1" | "+44" | "+81"; // آمریکا، بریتانیا، ژاپن
type PhoneNumber<C extends CountryCode, N extends string> = `${C}-${N}`;

type ValidUSPhoneNumber = PhoneNumber<"+1", "555-123-4567">; // type ValidUSPhoneNumber = "+1-555-123-4567"

//نکته: اعتبارسنجی پیچیده‌تر ممکن است نیاز به ترکیب انواع لیترال قالب با انواع شرطی داشته باشد.

این مثال نشان می‌دهد که چگونه می‌توانید یک نوع شماره تلفن پایه ایجاد کنید که فرمت خاصی را اعمال کند. اعتبارسنجی‌های پیچیده‌تر ممکن است شامل استفاده از انواع شرطی و الگوهای شبیه به عبارات منظم در داخل لیترال قالب باشد.

۳. تولید کد

از انواع لیترال قالب می‌توان برای تولید کد در زمان کامپایل استفاده کرد. به عنوان مثال، می‌توانید از آنها برای تولید نام کامپوننت‌های ری‌اکت بر اساس نام داده‌ای که نمایش می‌دهند، استفاده کنید. یک الگوی رایج، تولید نام کامپوننت‌ها به دنبال الگوی <Entity>Details است.

type Entity = "User" | "Product" | "Order";
type ComponentName<E extends Entity> = `${E}Details`;

type UserDetailsComponent = ComponentName<"User">; // type UserDetailsComponent = "UserDetails"

این به شما امکان می‌دهد تا به طور خودکار نام کامپوننت‌هایی را تولید کنید که سازگار و توصیفی هستند و خطر تداخل نام‌گذاری را کاهش داده و خوانایی کد را بهبود می‌بخشد.

۴. مدیریت رویدادها

انواع لیترال قالب برای تعریف نام رویدادها به روشی امن از نظر نوع عالی هستند و اطمینان می‌دهند که شنوندگان رویداد به درستی ثبت شده و گرداننده‌های رویداد (event handlers) داده‌های مورد انتظار را دریافت می‌کنند. سیستمی را در نظر بگیرید که در آن رویدادها بر اساس ماژول و نوع رویداد دسته‌بندی شده و با یک دو نقطه از هم جدا می‌شوند.

type Module = "user" | "product" | "order";
type EventType = "created" | "updated" | "deleted";
type EventName<M extends Module, E extends EventType> = `${M}:${E}`;

type UserCreatedEvent = EventName<"user", "created">; // type UserCreatedEvent = "user:created"

interface EventMap {
  [key: EventName<Module, EventType>]: (data: any) => void; //مثال: نوع برای مدیریت رویداد
}

این مثال نشان می‌دهد که چگونه می‌توان نام رویدادهایی را ایجاد کرد که از یک الگوی ثابت پیروی می‌کنند و ساختار کلی و امنیت نوع سیستم رویداد را بهبود می‌بخشند.

تکنیک‌های پیشرفته

۱. ترکیب با انواع شرطی

انواع لیترال قالب را می‌توان با انواع شرطی ترکیب کرد تا تبدیل‌های نوعی حتی پیچیده‌تری ایجاد شود. انواع شرطی به شما امکان می‌دهند تا انواعی را تعریف کنید که به انواع دیگر بستگی دارند و به شما امکان می‌دهند منطق پیچیده‌ای را در سطح نوع انجام دهید.

type ToUpperCase<S extends string> = S extends Uppercase<S> ? S : Uppercase<S>;

type MaybeUpperCase<S extends string, Upper extends boolean> = Upper extends true ? ToUpperCase<S> : S;

type Example = MaybeUpperCase<"hello", true>; // type Example = "HELLO"
type Example2 = MaybeUpperCase<"world", false>; // type Example2 = "world"

در این مثال، MaybeUpperCase یک رشته و یک مقدار بولی می‌گیرد. اگر مقدار بولی true باشد، رشته را به حروف بزرگ تبدیل می‌کند؛ در غیر این صورت، رشته را به همان شکل برمی‌گرداند. این نشان می‌دهد که چگونه می‌توانید انواع رشته‌ای را به صورت شرطی تغییر دهید.

۲. استفاده با انواع نگاشتی

انواع لیترال قالب را می‌توان با انواع نگاشتی (Mapped Types) برای تبدیل کلیدهای یک نوع شیء استفاده کرد. انواع نگاشتی به شما امکان می‌دهند با پیمایش کلیدهای یک نوع موجود و اعمال یک تبدیل بر روی هر کلید، انواع جدیدی ایجاد کنید. یک مورد استفاده رایج، افزودن پیشوند یا پسوند به کلیدهای شیء است.

type MyObject = {
  name: string;
  age: number;
};

type AddPrefix<T, Prefix extends string> = {
  [K in keyof T as `${Prefix}${string & K}`]: T[K];
};

type PrefixedObject = AddPrefix<MyObject, "data_">;
// type PrefixedObject = {
//    data_name: string;
//    data_age: number;
// }

در اینجا، AddPrefix یک نوع شیء و یک پیشوند می‌گیرد. سپس یک نوع شیء جدید با همان خصوصیات ایجاد می‌کند، اما با پیشوندی که به هر کلید اضافه شده است. این می‌تواند برای تولید اشیاء انتقال داده (DTOs) یا انواع دیگری که نیاز به تغییر نام خصوصیات دارند، مفید باشد.

۳. انواع ذاتی دستکاری رشته‌ها

تایپ‌اسکریپت چندین نوع ذاتی برای دستکاری رشته‌ها مانند Uppercase، Lowercase، Capitalize و Uncapitalize فراهم می‌کند که می‌توانند در ترکیب با انواع لیترال قالب برای انجام تبدیل‌های پیچیده‌تر رشته استفاده شوند.

type MyString = "hello world";

type CapitalizedString = Capitalize<MyString>; // type CapitalizedString = "Hello world"

type UpperCasedString = Uppercase<MyString>;   // type UpperCasedString = "HELLO WORLD"

این انواع ذاتی انجام دستکاری‌های رایج رشته را بدون نیاز به نوشتن منطق نوع سفارشی آسان‌تر می‌کنند.

بهترین شیوه‌ها

اشتباهات رایج

جایگزین‌ها

در حالی که انواع لیترال قالب روشی قدرتمند برای دستیابی به امنیت نوع در توسعه API ارائه می‌دهند، رویکردهای جایگزینی نیز وجود دارند که ممکن است در شرایط خاص مناسب‌تر باشند.

نتیجه‌گیری

انواع لیترال قالب تایپ‌اسکریپت ابزاری ارزشمند برای ایجاد APIهای امن از نظر نوع و قابل نگهداری هستند. آنها به شما امکان می‌دهند تا دستکاری رشته‌ها را در سطح نوع انجام دهید و به شما اجازه می‌دهند تا خطاها را در زمان کامپایل شناسایی کرده و کیفیت کلی کد خود را بهبود بخشید. با درک مفاهیم و تکنیک‌های مورد بحث در این مقاله، می‌توانید از انواع لیترال قالب برای ساخت APIهای قوی‌تر، قابل اعتمادتر و دوستدار توسعه‌دهنده استفاده کنید. چه در حال ساخت یک برنامه وب پیچیده باشید یا یک ابزار خط فرمان ساده، انواع لیترال قالب می‌توانند به شما در نوشتن کد تایپ‌اسکریپت بهتر کمک کنند.

برای درک کامل پتانسیل انواع لیترال قالب، بررسی مثال‌های بیشتر و آزمایش آنها در پروژه‌های خود را در نظر بگیرید. هرچه بیشتر از آنها استفاده کنید، با سینتکس و قابلیت‌های آنها راحت‌تر خواهید شد و این به شما امکان می‌دهد تا برنامه‌هایی واقعاً امن از نظر نوع و قوی ایجاد کنید.