کاوش جایگزینهای قدرتمند enum در TypeScript مانند const assertions و انواع union. درک مزایا، معایب و کاربردهای عملی آنها برای کدی تمیزتر و قابل نگهداریتر در یک زمینه توسعه جهانی.
جایگزینهای enum در TypeScript: پیمایش Const Assertions و انواع Union برای کد قوی
TypeScript، یک مجموعه فوقالعاده قدرتمند از JavaScript، تایپ استاتیک را به دنیای پویا توسعه وب میآورد. در میان ویژگیهای متعدد آن، کلیدواژه enum مدتهاست که برای تعریف مجموعهای از ثابتهای نامگذاری شده مورد استفاده قرار میگیرد. Enums راهی روشن برای نشان دادن مجموعهای ثابت از مقادیر مرتبط ارائه میدهند و قابلیت خوانایی و ایمنی نوع را افزایش میدهند.
با این حال، با بالغ شدن اکوسیستم TypeScript و رشد پروژهها از نظر پیچیدگی و مقیاس، توسعهدهندگان در سراسر جهان به طور فزایندهای در مورد سودمندی سنتی enums سوال میکنند. در حالی که برای موارد ساده سرراست است، enums رفتارهای خاصی و ویژگیهای زمان اجرا را معرفی میکنند که گاهی اوقات میتواند منجر به مشکلات غیرمنتظره، تأثیر بر اندازه بسته یا پیچیدگی بهینهسازیهای tree-shaking شود. این امر منجر به کاوش گستردهای در مورد جایگزینها شده است.
این راهنمای جامع به دو جایگزین برجسته و بسیار مؤثر برای enums TypeScript میپردازد: انواع Union با لیترالهای رشته/عددی و Const Assertions (as const). ما مکانیسمها، کاربردهای عملی، مزایا و مبادلات آنها را بررسی خواهیم کرد و شما را با دانش لازم برای تصمیمگیری آگاهانه در مورد طراحی برای پروژههای خود، صرف نظر از اندازه آنها یا تیم جهانی که روی آنها کار میکنند، مجهز میکنیم. هدف ما این است که شما را قادر سازیم تا کد TypeScript قویتر، قابل نگهداریتر و کارآمدتری بنویسید.
enum TypeScript: یک مرور سریع
قبل از اینکه به جایگزینها بپردازیم، بیایید نگاهی اجمالی به enum سنتی TypeScript بیندازیم. Enums به توسعهدهندگان اجازه میدهد تا مجموعهای از ثابتهای نامگذاری شده را تعریف کنند، که کد را خواناتر میکند و از پراکندگی «رشتههای جادویی» یا «اعداد جادویی» در سراسر یک برنامه جلوگیری میکند. آنها به دو شکل اصلی میآیند: عددی و رشتهای.
Enums عددی
به طور پیشفرض، enums TypeScript عددی هستند. اولین عضو با 0 مقداردهی اولیه میشود و هر عضو بعدی به طور خودکار افزایش مییابد.
enum Direction {
Up,
Down,
Left,
Right,
}
let currentDirection: Direction = Direction.Up;
console.log(currentDirection); // Outputs: 0
console.log(Direction.Left); // Outputs: 2
همچنین میتوانید اعضای enum عددی را به صورت دستی مقداردهی اولیه کنید:
enum StatusCode {
Success = 200,
NotFound = 404,
ServerError = 500,
}
let status: StatusCode = StatusCode.NotFound;
console.log(status); // Outputs: 404
یک ویژگی عجیب enums عددی، نقشهبرداری معکوس است. در زمان اجرا، یک enum عددی به یک شی جاوا اسکریپت کامپایل میشود که هم نامها را به مقادیر و هم مقادیر را به نامها نگاشت میکند.
enum UserRole {
Admin = 1,
Editor,
Viewer,
}
console.log(UserRole[1]); // Outputs: "Admin"
console.log(UserRole.Editor); // Outputs: 2
console.log(UserRole[2]); // Outputs: "Editor"
/*
Compiles to JavaScript:
var UserRole;
(function (UserRole) {
UserRole[UserRole["Admin"] = 1] = "Admin";
UserRole[UserRole["Editor"] = 2] = "Editor";
UserRole[UserRole["Viewer"] = 3] = "Viewer";
})(UserRole || (UserRole = {}));
*/
Enums رشتهای
en پس از آن، انواع Union با لیترالها، یک راهحل پاک، کارآمد و ایمن از نظر نوع ارائه میدهند که با روشهای توسعه مدرن جاوا اسکریپت همسو است.
جایگزین 2: Const Assertions (as const)
assertion as const، که در TypeScript 3.4 معرفی شد، ابزار دیگری است که قدرت باورنکردنی دارد و جایگزین بسیار خوبی برای enums ارائه میدهد، به خصوص زمانی که به یک شی زمان اجرا و استنتاج نوع قوی نیاز دارید. این به TypeScript اجازه میدهد تا باریکترین نوع ممکن را برای عبارات لیترال استنتاج کند.
Const Assertions چیستند؟
وقتی as const را به یک متغیر، یک آرایه یا یک شی لیترال اعمال میکنید، TypeScript تمام ویژگیهای موجود در آن لیترال را readonly در نظر میگیرد و انواع لیترال آنها را به جای انواع گستردهتر (به عنوان مثال، "foo" به جای string، 123 به جای number) استنتاج میکند. این امر امکان مشتق کردن انواع union بسیار خاص را از ساختارهای داده زمان اجرا فراهم میکند.
مثال عملی: ایجاد یک شی «شبه enum» با as const
بیایید به مثال وضعیت شغلی خود برگردیم. با as const، میتوانیم یک منبع واحد از حقیقت را برای وضعیتهای خود تعریف کنیم، که هم به عنوان یک شی زمان اجرا و هم به عنوان مبنایی برای تعاریف نوع عمل میکند.
const JobStatuses = {
PENDING: "PENDING",
IN_PROGRESS: "IN_PROGRESS",
COMPLETED: "COMPLETED",
FAILED: "FAILED",
} as const;
// JobStatuses.PENDING is now inferred as type "PENDING" (not just string)
// JobStatuses is inferred as type {
// readonly PENDING: "PENDING";
// readonly IN_PROGRESS: "IN_PROGRESS";
// readonly COMPLETED: "COMPLETED";
// readonly FAILED: "FAILED";
// }
در این مرحله، JobStatuses یک شی جاوا اسکریپت در زمان اجرا است، درست مانند یک enum معمولی. با این حال، استنتاج نوع آن بسیار دقیقتر است.
ترکیب با عملگرهای typeof و keyof برای انواع Union
قدرت واقعی زمانی آشکار میشود که as const را با عملگرهای typeof و keyof TypeScript ترکیب میکنیم تا یک نوع union را از مقادیر یا کلیدهای شیء مشتق کنیم.
const JobStatuses = {
PENDING: "PENDING",
IN_PROGRESS: "IN_PROGRESS",
COMPLETED: "COMPLETED",
FAILED: "FAILED",
} as const;
// Type representing the keys (e.g., "PENDING" | "IN_PROGRESS" | ...)
type JobStatusKeys = keyof typeof JobStatuses;
// Type representing the values (e.g., "PENDING" | "IN_PROGRESS" | ...)
type JobStatusValues = typeof JobStatuses[keyof typeof JobStatuses];
function processJobWithConstAssertion(status: JobStatusValues): void {
if (status === JobStatuses.COMPLETED) {
console.log("Job finished successfully.");
} else if (status === JobStatuses.FAILED) {
console.log("Job encountered an error.");
} else {
console.log(`Job is currently ${status}.`);
}
}
let currentJobStatusFromObject: JobStatusValues = JobStatuses.IN_PROGRESS;
processJobWithConstAssertion(currentJobStatusFromObject);
// This would result in a compile-time error:
// let invalidStatusFromObject: JobStatusValues = "CANCELLED"; // Error!
این الگو بهترینهای هر دو جهان را فراهم میکند: یک شیء زمان اجرا برای دسترسی به ویژگی مستقیم یا تکرار و یک نوع union در زمان کامپایل برای بررسی نوع دقیق.
مزایای Const Assertions با انواع Union مشتق شده
- منبع واحد حقیقت: شما ثابتهای خود را یک بار در یک شی جاوا اسکریپت ساده تعریف میکنید و هم دسترسی زمان اجرا و هم انواع زمان کامپایل را از آن مشتق میکنید. این امر افزونگی را به میزان قابل توجهی کاهش میدهد و قابلیت نگهداری را در سراسر تیمهای توسعه مختلف بهبود میبخشد.
- ایمنی نوع: شبیه به انواع union خالص، ایمنی نوع عالی را دریافت میکنید و اطمینان حاصل میکنید که فقط از مقادیر از پیش تعریف شده استفاده میشود.
- قابلیت تکرار در زمان اجرا: از آنجایی که
JobStatusesیک شی جاوا اسکریپت ساده است، میتوانید به راحتی با استفاده از روشهای استاندارد جاوا اسکریپت مانندObject.keys()،Object.values()یاObject.entries()بر روی کلیدها یا مقادیر آن تکرار کنید. این امر برای رابطهای کاربری پویا (به عنوان مثال، پر کردن منوهای کشویی) یا ورود به سیستم بسیار ارزشمند است. - دادههای مرتبط: این الگو به طور طبیعی از مرتبط کردن دادههای اضافی با هر عضو «enum» پشتیبانی میکند.
- پتانسیل بهتر Tree-Shaking (در مقایسه با Enums): در حالی که
as constیک شی زمان اجرا ایجاد میکند، یک شیء جاوا اسکریپت استاندارد است. باندلرهای مدرن به طور کلی در tree-shaking خواص استفاده نشده یا حتی اشیاء کامل در صورت عدم ارجاع، در مقایسه با خروجی کامپایل enum TypeScript، مؤثرتر هستند. با این حال، اگر شیء بزرگ باشد و تنها از چند ویژگی استفاده شود، در صورت وارد کردن آن به گونهای که از tree-shaking دانهای جلوگیری میکند، ممکن است کل شیء همچنان گنجانده شود. - انعطافپذیری: در صورت نیاز، میتوانید مقادیری را تعریف کنید که فقط رشتهها یا اعداد نباشند، بلکه اشیاء پیچیدهتری نیز باشند و این الگو را بسیار انعطافپذیر میکند.
const FileOperations = {
UPLOAD: {
label: "Upload File",
icon: "upload-icon.svg",
permission: "can_upload"
},
DOWNLOAD: {
label: "Download File",
icon: "download-icon.svg",
permission: "can_download"
},
DELETE: {
label: "Delete File",
icon: "delete-icon.svg",
permission: "can_delete"
},
} as const;
type FileOperationType = keyof typeof FileOperations; // "UPLOAD" | "DOWNLOAD" | "DELETE"
type FileOperationDetail = typeof FileOperations[keyof typeof FileOperations]; // { label: string; icon: string; permission: string; }
function performOperation(opType: FileOperationType) {
const details = FileOperations[opType];
console.log(`Performing: ${details.label} (Permission: ${details.permission})`);
}
performOperation("UPLOAD");
معایب Const Assertions
- حضور شی زمان اجرا: برخلاف انواع union خالص، این رویکرد همچنان یک شی جاوا اسکریپت در زمان اجرا ایجاد میکند. در حالی که یک شیء استاندارد است و اغلب برای tree-shaking بهتر از enums است، اما به طور کامل حذف نمیشود.
- تعریف نوع کمی بیشتر کلامی: مشتق کردن نوع union (
keyof typeof ...یاtypeof ...[keyof typeof ...]) به دستور زبان کمی بیشتر نیاز دارد تا صرفاً لیست کردن لیترالها برای یک نوع union. - امکان سوء استفاده: در صورت عدم استفاده دقیق، یک شیء
as constبسیار بزرگ همچنان میتواند به طور قابل توجهی به اندازه بسته کمک کند اگر محتوای آن در مرزهای ماژول به طور مؤثر tree-shaken نشود.
برای سناریوهایی که به هر دو بررسی نوع زمان کامپایل قوی و مجموعهای از مقادیر در زمان اجرا نیاز دارید که بتوان آنها را تکرار کرد یا دادههای مرتبط را ارائه داد، as const اغلب انتخاب ارجح در میان توسعهدهندگان TypeScript در سراسر جهان است.
مقایسه جایگزینها: چه زمانی از چه چیزی استفاده کنیم؟
انتخاب بین انواع union و const assertions تا حد زیادی به الزامات خاص شما در مورد حضور در زمان اجرا، قابلیت تکرار و اینکه آیا نیاز به مرتبط کردن دادههای اضافی با ثابتهای خود دارید یا خیر، بستگی دارد. بیایید عوامل تصمیمگیری را تجزیه کنیم.
سادگی در مقابل استحکام
- انواع Union: وقتی فقط به مجموعهای از مقادیر رشتهای یا عددی مجزا و ایمن از نظر نوع در زمان کامپایل نیاز دارید، سادگی نهایی را ارائه میدهند. آنها سبکترین گزینه هستند.
- Const Assertions: هنگامی که به ایمنی نوع در زمان کامپایل و یک شیء زمان اجرا نیاز دارید که بتوان آن را پرس و جو کرد، تکرار کرد یا با ابردادههای اضافی گسترش داد، یک الگو قویتر ارائه میدهند. تنظیم اولیه کمی پرمایهتر است، اما در ویژگیها نتیجه میدهد.
حضور زمان اجرا در مقابل زمان کامپایل
- انواع Union: صرفاً سازههای زمان کامپایل هستند. آنها به هیچ وجه کد جاوا اسکریپت تولید نمیکنند. این برای برنامههایی ایدهآل است که در آنها به حداقل رساندن اندازه بسته بسیار مهم است و خود مقادیر بدون نیاز به دسترسی به آنها به عنوان یک شیء در زمان اجرا کافی هستند.
- Const Assertions: یک شیء جاوا اسکریپت ساده در زمان اجرا تولید میکنند. این شیء در کد جاوا اسکریپت شما قابل دسترسی و استفاده است. در حالی که به اندازه بسته میافزاید، به طور کلی از enums TypeScript کارآمدتر است و کاندیداهای بهتری برای tree-shaking هستند.
الزامات قابلیت تکرار
- انواع Union: یک راه مستقیم برای تکرار بر روی تمام مقادیر ممکن در زمان اجرا ارائه نمیدهند. اگر نیاز به پر کردن یک منوی کشویی یا نمایش تمام گزینهها دارید، باید یک آرایه جداگانه از این مقادیر تعریف کنید، که به طور بالقوه منجر به تکرار میشود.
- Const Assertions: در اینجا برتری دارند. از آنجایی که شما با یک شیء جاوا اسکریپت استاندارد کار میکنید، میتوانید به راحتی از
Object.keys()،Object.values()یاObject.entries()برای دریافت یک آرایه از کلیدها، مقادیر یا جفتهای کلید-مقدار، به ترتیب استفاده کنید. این امر آنها را برای رابطهای کاربری پویا یا هر سناریویی که به شمردن زمان اجرا نیاز دارد، عالی میکند.
const PaymentMethods = {
CREDIT_CARD: "Credit Card",
PAYPAL: "PayPal",
BANK_TRANSFER: "Bank Transfer",
} as const;
type PaymentMethodType = keyof typeof PaymentMethods;
// Get all keys (e.g., for internal logic)
const methodKeys = Object.keys(PaymentMethods) as PaymentMethodType[];
console.log(methodKeys); // ["CREDIT_CARD", "PAYPAL", "BANK_TRANSFER"]
// Get all values (e.g., for display in a dropdown)
const methodLabels = Object.values(PaymentMethods);
console.log(methodLabels); // ["Credit Card", "PayPal", "Bank Transfer"]
// Get key-value pairs (e.g., for mapping)
const methodEntries = Object.entries(PaymentMethods);
console.log(methodEntries); // [["CREDIT_CARD", "Credit Card"], ...]
پیامدهای Tree-Shaking
- انواع Union: از آنجا که فقط زمان کامپایل هستند، ذاتاً tree-shakeable هستند.
- Const Assertions: در حالی که آنها یک شیء زمان اجرا ایجاد میکنند، باندلرهای مدرن اغلب میتوانند خواص استفاده نشده این شیء را به طور مؤثرتری از اشیاء enum تولید شده توسط TypeScript tree-shake کنند. با این حال، اگر کل شیء وارد و ارجاع شود، احتمالاً گنجانده میشود. طراحی ماژول با دقت میتواند کمک کند.
بهترین روشها و رویکردهای ترکیبی
همیشه یک وضعیت «یا/یا» نیست. اغلب، بهترین راهحل شامل یک رویکرد ترکیبی است، به خصوص در برنامههای بزرگ و بینالمللی شده:
- برای پرچمها یا شناساگرهای ساده و کاملاً داخلی که هرگز نیازی به تکرار یا داشتن دادههای مرتبط ندارند، انواع Union به طور کلی کارآمدترین و تمیزترین انتخاب هستند.
- برای مجموعهای از ثابتهایی که باید تکرار شوند، در رابطهای کاربری نمایش داده شوند یا دارای ابردادههای غنی مرتبط (مانند برچسبها، نمادها یا مجوزها) هستند، الگوی Const Assertions برتر است.
- ترکیب برای خوانایی و محلیسازی: بسیاری از تیمها از
as constبرای شناساگرهای داخلی استفاده میکنند و سپس برچسبهای نمایش محلیشده را از یک سیستم بینالمللیسازی (i18n) جداگانه مشتق میکنند.
// src/constants/order-status.ts
const OrderStatuses = {
PENDING: "PENDING",
PROCESSING: "PROCESSING",
SHIPPED: "SHIPPED",
DELIVERED: "DELIVERED",
CANCELLED: "CANCELLED",
} as const;
type OrderStatus = typeof OrderStatuses[keyof typeof OrderStatuses];
export { OrderStatuses, type OrderStatus };
// src/i18n/en.json
{
"orderStatus": {
"PENDING": "Pending Confirmation",
"PROCESSING": "Processing Order",
"SHIPPED": "Shipped",
"DELIVERED": "Delivered",
"CANCELLED": "Cancelled"
}
}
// src/components/OrderStatusDisplay.tsx
import { OrderStatuses, type OrderStatus } from "../constants/order-status";
import { useTranslation } from "react-i18next"; // Example i18n library
interface OrderStatusDisplayProps {
status: OrderStatus;
}
function OrderStatusDisplay({ status }: OrderStatusDisplayProps) {
const { t } = useTranslation();
const displayLabel = t(`orderStatus.${status}`);
return <span>Status: {displayLabel}</span>;
}
// Usage:
// <OrderStatusDisplay status={OrderStatuses.DELIVERED} />
این رویکرد ترکیبی از ایمنی نوع و قابلیت تکرار زمان اجرا as const استفاده میکند و در عین حال برچسبهای نمایش محلی شده را جدا و قابل مدیریت نگه میدارد، که یک ملاحظه حیاتی برای برنامههای جهانی است.
الگوهای پیشرفته و ملاحظات
فراتر از استفاده اولیه، انواع union و const assertions میتوانند در الگوهای پیچیدهتری ادغام شوند تا کیفیت و قابلیت نگهداری کد را بیشتر افزایش دهند.
استفاده از Type Guards با انواع Union
هنگام کار با انواع union، به خصوص زمانی که union شامل انواع متنوع (نه فقط لیترالها) باشد، type guards برای محدود کردن انواع ضروری میشوند. با انواع union لیترال، unionهای تبعیضآمیز قدرت زیادی ارائه میدهند.
type SuccessEvent = { type: "SUCCESS"; data: any; };
type ErrorEvent = { type: "ERROR"; message: string; code: number; };
type SystemEvent = SuccessEvent | ErrorEvent;
function handleSystemEvent(event: SystemEvent) {
if (event.type === "SUCCESS") {
console.log("Data received:", event.data);
// event is now narrowed to SuccessEvent
} else {
console.log("Error occurred:", event.message, "Code:", event.code);
// event is now narrowed to ErrorEvent
}
}
handleSystemEvent({ type: "SUCCESS", data: { user: "Alice" } });
handleSystemEvent({ type: "ERROR", message: "Network failure", code: 503 });
این الگو، که اغلب «unionهای تبعیضآمیز» نامیده میشود، فوقالعاده قوی و ایمن از نظر نوع است و تضمینهای زمان کامپایل را در مورد ساختار دادههای شما بر اساس یک ویژگی لیترال مشترک (متمایزکننده) ارائه میدهد.
Object.values() با as const و Type Assertions
هنگام استفاده از الگوی as const، Object.values() میتواند بسیار مفید باشد. با این حال، استنتاج پیشفرض TypeScript برای Object.values() ممکن است گستردهتر از حد مطلوب باشد (به عنوان مثال، string[] به جای union خاصی از لیترالها). ممکن است برای دقت به یک type assertion نیاز داشته باشید.
const Statuses = {
ACTIVE: "Active",
INACTIVE: "Inactive",
PENDING: "Pending",
} as const;
type StatusValue = typeof Statuses[keyof typeof Statuses]; // "Active" | "Inactive" | "Pending"
// Object.values(Statuses) is inferred as (string | "Active" | "Inactive" | "Pending")[]
// We can assert it more narrowly if needed:
const allStatusValues: StatusValue[] = Object.values(Statuses);
console.log(allStatusValues); // ["Active", "Inactive", "Pending"]
// For a dropdown, you might pair values with labels if they differ
const statusOptions = Object.entries(Statuses).map(([key, value]) => ({
value: key, // Use the key as the actual identifier
label: value // Use the value as the display label
}));
console.log(statusOptions);
/*
[
{ value: "ACTIVE", label: "Active" },
{ value: "INACTIVE", label: "Inactive" },
{ value: "PENDING", label: "Pending" }
]
*/
این نشان میدهد که چگونه یک آرایه با نوع قوی از مقادیر مناسب برای عناصر رابط کاربری در حالی که انواع لیترال را حفظ میکنید، بدست آورید.
بینالمللیسازی (i18n) و برچسبهای محلیشده
برای برنامههای جهانی، مدیریت رشتههای محلی شده از اهمیت بالایی برخوردار است. در حالی که enums TypeScript و جایگزینهای آنها شناساگرهای داخلی را ارائه میدهند، برچسبهای نمایش اغلب نیاز به جدا شدن برای i18n دارند. الگوی as const به زیبایی مکمل سیستمهای i18n است.
شما شناساگرهای داخلی و تغییرناپذیر خود را با استفاده از as const تعریف میکنید. این شناساگرها در سراسر تمام زبانها سازگار هستند و به عنوان کلید برای فایلهای ترجمه شما عمل میکنند. سپس رشتههای نمایش واقعی از یک کتابخانه i18n (به عنوان مثال، react-i18next، vue-i18n، FormatJS) بر اساس زبان انتخابی کاربر واکشی میشوند.
// app/features/product/constants.ts
export const ProductCategories = {
ELECTRONICS: "ELECTRONICS",
APPAREL: "APPAREL",
HOME_GOODS: "HOME_GOODS",
BOOKS: "BOOKS",
} as const;
export type ProductCategory = typeof ProductCategories[keyof typeof ProductCategories];
// app/i18n/locales/en.json
{
"productCategories": {
"ELECTRONICS": "Electronics",
"APPAREL": "Apparel & Accessories",
"HOME_GOODS": "Home Goods",
"BOOKS": "Books"
}
}
// app/i18n/locales/es.json
{
"productCategories": {
"ELECTRONICS": "Electrónica",
"APPAREL": "Ropa y Accesorios",
"HOME_GOODS": "Artículos para el hogar",
"BOOKS": "Libros"
}
}
// app/components/ProductCategorySelector.tsx
import { ProductCategories, type ProductCategory } from "../features/product/constants";
import { useTranslation } from "react-i18next";
function ProductCategorySelector() {
const { t } = useTranslation();
return (
<select>
{Object.values(ProductCategories).map(categoryKey => (
<option key={categoryKey} value={categoryKey}>
{t(`productCategories.${categoryKey}`)}
</option>
))}
</select>
);
}
این جداسازی دغدغهها برای برنامههای جهانی مقیاسپذیر بسیار مهم است. انواع TypeScript تضمین میکنند که شما همیشه از کلیدهای معتبر استفاده میکنید و سیستم i18n لایه ارائه را بر اساس زبان انتخابی کاربر مدیریت میکند. این امر از قرار دادن مستقیم رشتههای وابسته به زبان در منطق اصلی برنامه شما جلوگیری میکند، که یک ضدالگوی رایج برای تیمهای بینالمللی است.
نتیجهگیری: توانمندسازی انتخابهای طراحی TypeScript شما
از آنجایی که TypeScript به تکامل خود ادامه میدهد و توسعهدهندگان را در سراسر جهان قادر میسازد تا برنامههای قویتر و مقیاسپذیرتری بسازند، درک ویژگیها و جایگزینهای ظریف آن به طور فزایندهای مهم میشود. در حالی که کلیدواژه enum TypeScript راهی راحت برای تعریف ثابتهای نامگذاری شده ارائه میدهد، ردپای زمان اجرای آن، محدودیتهای tree-shaking و پیچیدگیهای نگاشت معکوس، اغلب جایگزینهای مدرن را برای پروژههای حساس به عملکرد یا در مقیاس بزرگ جذابتر میکند.
انواع Union با لیترالهای رشته/عددی به عنوان راهحل سادهترین و زمان کامپایلمحورترین راه حل برجسته هستند. آنها ایمنی نوع بینقص را بدون تولید هیچ جاوا اسکریپتی در زمان اجرا ارائه میدهند و آنها را برای سناریوهایی که در آنها اندازه بسته حداقل و tree-shaking حداکثری اولویت دارند و شمارش زمان اجرا مدنظر نیست، ایدهآل میکنند.
از طرف دیگر، Const Assertions (as const) همراه با typeof و keyof یک الگو بسیار انعطافپذیر و قدرتمند را ارائه میدهند. آنها یک منبع واحد از حقیقت را برای ثابتهای شما، ایمنی نوع زمان کامپایل قوی و توانایی حیاتی برای تکرار بر روی مقادیر در زمان اجرا ارائه میدهند. این رویکرد به ویژه برای موقعیتهایی مناسب است که در آنها نیاز به مرتبط کردن دادههای اضافی با ثابتهای خود، پر کردن رابطهای کاربری پویا یا یکپارچهسازی یکپارچه با سیستمهای بینالمللیسازی دارید.
با در نظر گرفتن دقیق مبادلات - ردپای زمان اجرا، نیازهای قابلیت تکرار، و پیچیدگی دادههای مرتبط - میتوانید تصمیمات آگاهانهای بگیرید که منجر به کد TypeScript تمیزتر، کارآمدتر و قابل نگهداریتر میشود. پذیرش این جایگزینها فقط در مورد نوشتن TypeScript «مدرن» نیست. این در مورد انتخابهای معماری عمدی است که عملکرد، تجربه توسعهدهنده و پایداری بلندمدت برنامه شما را برای مخاطبان جهانی افزایش میدهد.
با انتخاب ابزار مناسب برای کار مناسب، فراتر از enum پیشفرض بروید، زمانی که جایگزینهای بهتری وجود دارند، توسعه TypeScript خود را توانمند کنید.