نگهبان های نوع (Type Guards)
«نگهبان نوع (Type Guard)» یعنی چک کردن نوع در زمان اجرا. سپس تایپ اسکریپت داخل همان بلوک، نوع دقیق را می فهمد. بنابراین خطا کم می شود و کد خواناتر می شود. مثل ناظم مدرسه که مسیر درست را مشخص می کند.
نگهبان های نوع با typeof
عملگر typeof نوع مقدارهای ساده را چک می کند؛ مثل string یا number.
function formatValue(value: string | number): string {
if (typeof value === 'string') {
return value.trim().toUpperCase();
} else {
return value.toFixed(2);
}
}
const result1: string = formatValue(' hello ');
const result2: string = formatValue(42.1234);
نگهبان های نوع با instanceof
با instanceof می فهمیم یک شیء از کدام کلاس است؛ مثل کارت دانش آموزی.
class Bird {
fly(): void {
console.log('Flying...');
}
}
class Fish {
swim(): void {
console.log('Swimming...');
}
}
function move(animal: Bird | Fish): void {
if (animal instanceof Bird) {
animal.fly();
} else {
animal.swim();
}
}
نگهبان های نوعِ سفارشی (Type Predicate)
خودت تابع نگهبان بساز. امضای value is Type به تایپ اسکریپت می گوید نوع را تنگ کند.
interface Car {
make: string;
model: string;
year: number;
}
interface Motorcycle {
make: string;
model: string;
year: number;
type: 'sport' | 'cruiser';
}
function isCar(vehicle: Car | Motorcycle): vehicle is Car {
return (vehicle as Motorcycle).type === undefined;
}
function displayVehicleInfo(vehicle: Car | Motorcycle): void {
console.log('Make: ' + vehicle.make + ', Model: ' + vehicle.model + ', Year: ' + vehicle.year);
if (isCar(vehicle)) {
console.log('This is a car');
} else {
console.log('This is a ' + vehicle.type + ' motorcycle');
}
}
اتحادهای متمایز (Discriminated Unions)
یک ویژگی ثابت مثل kind می گذاری. سپس با switch دقیق محدود می کنی.
interface Circle {
kind: 'circle';
radius: number;
}
interface Square {
kind: 'square';
sideLength: number;
}
type Shape = Circle | Square;
function calculateArea(shape: Shape): number {
switch (shape.kind) {
case 'circle': {
return Math.PI * (shape.radius ** 2);
}
case 'square': {
return shape.sideLength ** 2;
}
}
}
نگهبان با عملگر in
اگر ویژگی خاصی بود، نوعش را حدس بزن. ساده و سریع.
interface Dog {
bark(): void;
}
interface Cat {
meow(): void;
}
function makeSound(animal: Dog | Cat): void {
if ('bark' in animal) {
animal.bark();
} else {
animal.meow();
}
}
توابع Assert (تأییدگر نوع)
تابع تأییدگر، روی ورودی چک می کند و در خطا پرتاب می کند. پس ایمن تر است.
function assertIsString(value: unknown): asserts value is string {
if (typeof value !== 'string') {
throw new Error('Value is not a string');
}
}
function assert(condition: unknown, message: string): asserts condition {
if (!condition) {
throw new Error(message);
}
}
function processInput(input: unknown): void {
assertIsString(input);
console.log(input.toUpperCase());
}
function processNumber(value: unknown): number {
assert(typeof value === 'number', 'Value must be a number');
return value * 2;
}
گام های عملی
- نوع های مبهم را شناسایی کن.
- با
typeofیاinشروع کن. - برای کلاس ها از
instanceofاستفاده کن. - اگر پیچیده شد، تابع نگهبان بساز.
- در ورودی های حساس،
assertاضافه کن.
جمع بندی سریع
typeofبرای نوع های ساده عالی است.instanceofمخصوص کلاس هاست.- Predicate سفارشی، خوانایی را بالا می برد.
- اتحاد متمایز، سوییچ را ایمن می کند.
assertخطاها را جلوتر می گیرد.
ادامه مطالعه: صفحه انواع پیشرفته و نوع های شرطی. همچنین برای مرجع بیرونی، راهنمای W3Schools همین بخش را ببین. اگر لازم شد، از لینک نگهبان های نوع تایپ اسکریپت استفاده کن.