با امضاهای تأیید تایپاسکریپت برای اعتبارسنجی نوع در زمان اجرا آشنا شوید تا قابلیت اطمینان کد را افزایش داده و از خطاهای غیرمنتظره جلوگیری کنید. مثالهای عملی و بهترین شیوهها را بیاموزید.
امضاهای تأیید تایپاسکریپت: اعتبارسنجی نوع در زمان اجرا برای کدی استوار
تایپاسکریپت بررسی نوع ایستا (static type checking) فوقالعادهای را در طول توسعه فراهم میکند و خطاهای بالقوه را قبل از زمان اجرا شناسایی میکند. با این حال، گاهی اوقات لازم است ایمنی نوع را در زمان اجرا نیز تضمین کنید. اینجاست که امضاهای تأیید (assertion signatures) وارد عمل میشوند. آنها به شما این امکان را میدهند تا توابعی تعریف کنید که نه تنها نوع یک مقدار را بررسی میکنند، بلکه به تایپاسکریپت نیز اطلاع میدهند که نوع آن مقدار بر اساس نتیجه بررسی، محدودتر (narrowed) شده است.
امضاهای تأیید چه هستند؟
امضای تأیید یک نوع خاص از امضای تابع در تایپاسکریپت است که از کلمه کلیدی asserts
استفاده میکند. این امضا به تایپاسکریپت میگوید که اگر تابع بدون پرتاب خطا بازگردد، آنگاه یک شرط خاص در مورد نوع یک آرگومان تضمین شده است که درست باشد. این به شما امکان میدهد تا انواع را به گونهای اصلاح کنید که کامپایلر آن را درک کند، حتی زمانی که نمیتواند به طور خودکار نوع را بر اساس کد استنتاج کند.
سینتکس اصلی آن به این صورت است:
function assertsCondition(argument: Type): asserts argument is NarrowedType {
// ... implementation that checks the condition and throws if it's false ...
}
assertsCondition
: نام تابع شما.argument: Type
: آرگومانی که میخواهید نوع آن را بررسی کنید.asserts argument is NarrowedType
: این همان امضای تأیید است. به تایپاسکریپت میگوید که اگرassertsCondition(argument)
بدون پرتاب خطا بازگردد، آنگاه تایپاسکریپت میتواند باargument
به عنوان نوعNarrowedType
رفتار کند.
چرا از امضاهای تأیید استفاده کنیم؟
امضاهای تأیید چندین مزیت را فراهم میکنند:
- اعتبارسنجی نوع در زمان اجرا: به شما امکان میدهند نوع یک مقدار را در زمان اجرا اعتبارسنجی کنید و از خطاهای غیرمنتظره ناشی از دادههای نادرست جلوگیری کنید.
- ایمنی بهبود یافته کد: با اعمال محدودیتهای نوع در زمان اجرا، میتوانید خطر بروز باگها را کاهش داده و قابلیت اطمینان کلی کد خود را بهبود بخشید.
- محدود کردن نوع (Type Narrowing): امضاهای تأیید به تایپاسکریپت اجازه میدهند تا نوع یک متغیر را بر اساس نتیجه یک بررسی در زمان اجرا محدود کند، که امکان بررسی دقیقتر نوع را در کدهای بعدی فراهم میکند.
- خوانایی بهبود یافته کد: آنها کد شما را در مورد انواع مورد انتظار صریحتر میکنند و درک و نگهداری آن را آسانتر میسازند.
مثالهای عملی
مثال ۱: بررسی برای یک رشته (String)
بیایید تابعی ایجاد کنیم که تأیید کند یک مقدار، رشته است. اگر رشته نباشد، خطا پرتاب میکند.
function assertIsString(value: any): asserts value is string {
if (typeof value !== 'string') {
throw new Error(`Expected a string, but received ${typeof value}`);
}
}
function processString(input: any) {
assertIsString(input);
// TypeScript now knows that 'input' is a string
console.log(input.toUpperCase());
}
processString("hello"); // Works fine
// processString(123); // Throws an error at runtime
در این مثال، assertIsString
بررسی میکند که آیا مقدار ورودی یک رشته است یا خیر. اگر نباشد، خطا پرتاب میکند. اگر بدون پرتاب خطا بازگردد، تایپاسکریپت میداند که input
یک رشته است و به شما اجازه میدهد تا با خیال راحت متدهای رشتهای مانند toUpperCase()
را فراخوانی کنید.
مثال ۲: بررسی برای یک ساختار شیء خاص
فرض کنید در حال کار با دادههایی هستید که از یک API دریافت شدهاند و میخواهید قبل از پردازش، اطمینان حاصل کنید که این دادهها با یک ساختار شیء خاص مطابقت دارند. بیایید فرض کنیم شما منتظر یک شیء با خصوصیات name
(رشته) و age
(عدد) هستید.
interface Person {
name: string;
age: number;
}
function assertIsPerson(value: any): asserts value is Person {
if (typeof value !== 'object' || value === null) {
throw new Error(`Expected an object, but received ${typeof value}`);
}
if (!('name' in value) || typeof value.name !== 'string') {
throw new Error(`Expected a string 'name' property`);
}
if (!('age' in value) || typeof value.age !== 'number') {
throw new Error(`Expected a number 'age' property`);
}
}
function processPerson(data: any) {
assertIsPerson(data);
// TypeScript now knows that 'data' is a Person
console.log(`Name: ${data.name}, Age: ${data.age}`);
}
processPerson({ name: "Alice", age: 30 }); // Works fine
// processPerson({ name: "Bob", age: "30" }); // Throws an error at runtime
// processPerson({ name: "Charlie" }); // Throws an error at runtime
در اینجا، assertIsPerson
بررسی میکند که آیا مقدار ورودی یک شیء با خصوصیات و انواع مورد نیاز است یا خیر. اگر هر یک از بررسیها ناموفق باشد، خطا پرتاب میکند. در غیر این صورت، تایپاسکریپت با data
به عنوان یک شیء Person
رفتار میکند.
مثال ۳: بررسی برای یک مقدار Enum خاص
یک enum را در نظر بگیرید که وضعیتهای مختلف سفارش را نشان میدهد.
enum OrderStatus {
PENDING = "PENDING",
PROCESSING = "PROCESSING",
SHIPPED = "SHIPPED",
DELIVERED = "DELIVERED",
}
function assertIsOrderStatus(value: any): asserts value is OrderStatus {
if (!Object.values(OrderStatus).includes(value)) {
throw new Error(`Expected OrderStatus, but received ${value}`);
}
}
function processOrder(status: any) {
assertIsOrderStatus(status);
// TypeScript now knows that 'status' is an OrderStatus
console.log(`Order status: ${status}`);
}
processOrder(OrderStatus.SHIPPED); // Works fine
// processOrder("CANCELLED"); // Throws an error at runtime
در این مثال، assertIsOrderStatus
تضمین میکند که مقدار ورودی یک مقدار معتبر از enum OrderStatus
است. اگر نباشد، خطا پرتاب میکند. این به جلوگیری از پردازش وضعیتهای سفارش نامعتبر کمک میکند.
مثال ۴: استفاده از توابع پیشبینی نوع (type predicates) با توابع تأیید
امکان ترکیب توابع پیشبینی نوع و توابع تأیید برای انعطافپذیری بیشتر وجود دارد.
function isString(value: any): value is string {
return typeof value === 'string';
}
function assertString(value: any): asserts value is string {
if (!isString(value)) {
throw new Error(`Expected a string, but received ${typeof value}`);
}
}
function processValue(input: any) {
assertString(input);
console.log(input.toUpperCase());
}
processValue("TypeScript"); // Works
// processValue(123); // Throws
بهترین شیوهها
- تأییدها را مختصر نگه دارید: بر روی اعتبارسنجی خصوصیات یا شرایط ضروری که برای عملکرد صحیح کد شما لازم است تمرکز کنید. از تأییدهای بیش از حد پیچیده که ممکن است سرعت برنامه شما را کاهش دهند، خودداری کنید.
- پیامهای خطای واضح ارائه دهید: پیامهای خطای آموزندهای را شامل کنید که به توسعهدهندگان کمک میکند تا به سرعت علت خطا و نحوه رفع آن را شناسایی کنند. از زبان خاصی استفاده کنید که کاربر را راهنمایی کند. به عنوان مثال، به جای گفتن "داده نامعتبر"، بگویید "انتظار یک شیء با خصوصیات 'name' و 'age' میرفت."
- از توابع پیشبینی نوع برای بررسیهای پیچیده استفاده کنید: اگر منطق اعتبارسنجی شما پیچیده است، استفاده از توابع پیشبینی نوع را برای کپسولهسازی منطق بررسی نوع و بهبود خوانایی کد در نظر بگیرید.
- پیامدهای عملکرد را در نظر بگیرید: اعتبارسنجی نوع در زمان اجرا به برنامه شما سربار اضافه میکند. از امضاهای تأیید با احتیاط و فقط در مواقع ضروری استفاده کنید. بررسی نوع ایستا باید در صورت امکان ترجیح داده شود.
- خطاها را به درستی مدیریت کنید: اطمینان حاصل کنید که برنامه شما خطاهای پرتاب شده توسط توابع تأیید را به درستی مدیریت میکند تا از کرش کردن جلوگیری کرده و تجربه کاربری خوبی را فراهم کند. کدهای مستعد خطا را در بلوکهای try-catch قرار دهید.
- تأییدهای خود را مستند کنید: هدف و رفتار توابع تأیید خود را به وضوح مستند کنید و شرایطی را که بررسی میکنند و انواع مورد انتظار را توضیح دهید. این به سایر توسعهدهندگان کمک میکند تا کد شما را به درستی درک کرده و استفاده کنند.
موارد استفاده در صنایع مختلف
امضاهای تأیید میتوانند در صنایع مختلفی مفید باشند:
- تجارت الکترونیک: اعتبارسنجی ورودی کاربر در هنگام تسویه حساب برای اطمینان از صحت آدرسهای حمل و نقل، اطلاعات پرداخت و جزئیات سفارش.
- امور مالی: تأیید دادههای مالی از منابع خارجی، مانند قیمت سهام یا نرخ ارز، قبل از استفاده از آنها در محاسبات یا گزارشها.
- مراقبتهای بهداشتی: اطمینان از اینکه دادههای بیمار با فرمتها و استانداردهای خاصی مانند سوابق پزشکی یا نتایج آزمایشگاهی مطابقت دارد.
- تولید: اعتبارسنجی دادههای حسگرها و ماشینآلات برای اطمینان از اینکه فرآیندهای تولید به آرامی و با کارایی در حال اجرا هستند.
- لجستیک: بررسی صحت و کامل بودن دادههای حمل و نقل، مانند شمارههای رهگیری و آدرسهای تحویل.
جایگزینهای امضاهای تأیید
در حالی که امضاهای تأیید ابزار قدرتمندی هستند، رویکردهای دیگری نیز برای اعتبارسنجی نوع در زمان اجرا در تایپاسکریپت وجود دارد:
- محافظهای نوع (Type Guards): محافظهای نوع توابعی هستند که یک مقدار بولی برمیگردانند که نشان میدهد آیا یک مقدار از یک نوع خاص است یا خیر. میتوان از آنها برای محدود کردن نوع یک متغیر در یک بلوک شرطی استفاده کرد. با این حال، برخلاف امضاهای تأیید، آنها در صورت عدم موفقیت بررسی نوع، خطا پرتاب نمیکنند.
- کتابخانههای بررسی نوع در زمان اجرا: کتابخانههایی مانند
io-ts
،zod
وyup
قابلیتهای جامع بررسی نوع در زمان اجرا را فراهم میکنند، از جمله اعتبارسنجی اسکما و تبدیل دادهها. این کتابخانهها میتوانند به ویژه هنگام کار با ساختارهای داده پیچیده یا APIهای خارجی مفید باشند.
نتیجهگیری
امضاهای تأیید تایپاسکریپت یک مکانیسم قدرتمند برای اجرای اعتبارسنجی نوع در زمان اجرا فراهم میکنند که قابلیت اطمینان کد را افزایش داده و از خطاهای غیرمنتظره جلوگیری میکند. با تعریف توابعی که نوع یک مقدار را تأیید میکنند، میتوانید ایمنی نوع را بهبود بخشید، انواع را محدود کنید و کد خود را صریحتر و قابل نگهداریتر کنید. در حالی که جایگزینهایی وجود دارد، امضاهای تأیید راهی سبک و مؤثر برای افزودن بررسیهای نوع در زمان اجرا به پروژههای تایپاسکریپت شما ارائه میدهند. با پیروی از بهترین شیوهها و در نظر گرفتن دقیق پیامدهای عملکرد، میتوانید از امضاهای تأیید برای ساخت برنامههای قویتر و قابل اطمینانتر استفاده کنید.
به یاد داشته باشید که امضاهای تأیید زمانی بیشترین تأثیر را دارند که در کنار ویژگیهای بررسی نوع ایستا تایپاسکریپت استفاده شوند. آنها باید برای تکمیل بررسی نوع ایستا استفاده شوند، نه جایگزینی آن. با ترکیب اعتبارسنجی نوع ایستا و در زمان اجرا، میتوانید به سطح بالایی از ایمنی کد دست یابید و از بسیاری از خطاهای رایج جلوگیری کنید.