۵۰ درصد تخفیف ویژه برای همه دوره‌ها از شنبه

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

Type Predicate چیست؟

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

سینتکس تابع type predicate به شکل زیر می‌باشد:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
function isOfType(arg: any): arg is Type {
// ... logic
}
function isOfType(arg: any): arg is Type { // ... logic }
function isOfType(arg: any): arg is Type {
    // ... logic
}

arg is Type
arg is Type سینتکس type predicate است. این کد به تایپ اسکریپت سیگنال می‌دهد که وقتی تابع مقدار
true
true را return می‌کند، فراخوانی کننده تابع می‌تواند مطمئن شود که
arg
arg از نوع
Type
Type است.

چرا Type Predicateها مفید هستند؟

سناریویی را در نظر می‌گیریم که در آن یک union type (به عنوان مثال،

string | number
string | number) داریم و می‌خواهیم کدهای مختلفی را بر اساس تایپ اجرا کنیم. روش استاندارد، استفاده از type guardها می‌باشد:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
function processInput(input: string | number) {
if (typeof input === 'string') {
console.log(input.toUpperCase());
} else {
console.log(input.toFixed(2));
}
}
function processInput(input: string | number) { if (typeof input === 'string') { console.log(input.toUpperCase()); } else { console.log(input.toFixed(2)); } }
function processInput(input: string | number) {
    if (typeof input === 'string') {
        console.log(input.toUpperCase());
    } else {
        console.log(input.toFixed(2));
    }
}

در حالی که

typeof
typeof و
instanceof
instanceof هر دو مفید هستند، اما همه موارد را پوشش نمی‌دهند. اینجاست که type predicateها مطرح می‌شوند. آن‌ها به توسعه‌دهندگان اجازه می‌دهند تا type guardهای سفارشی ایجاد کنند که تایپ‌ها را بر اساس منطق سفارشی محدود می‌کند.

بررسی مثال‌هایی از Type Predicate

مثال اول با Interface

فرض کنید دو interface

Cat
Cat و
Dog
Dog داریم و می‌خواهیم بررسی کنیم که آیا یک حیوان
Cat
Cat است یا خیر:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
interface Cat {
purr(): void;
}
interface Dog {
bark(): void;
}
function isCat(animal: Cat | Dog): animal is Cat {
return (animal as Cat).purr !== undefined;
}
interface Cat { purr(): void; } interface Dog { bark(): void; } function isCat(animal: Cat | Dog): animal is Cat { return (animal as Cat).purr !== undefined; }
interface Cat {
    purr(): void;
}

interface Dog {
    bark(): void;
}

function isCat(animal: Cat | Dog): animal is Cat {
    return (animal as Cat).purr !== undefined;
}

اکنون، هر زمان که از

isCat
isCat در یک حالت شرطی استفاده می‌کنیم، تایپ اسکریپت تایپ آن را می‌داند:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const myPet: Cat | Dog = getPetSomehow();
if (isCat(myPet)) {
myPet.purr(); // TypeScript knows `myPet` is a `Cat` here.
} else {
myPet.bark();
}
const myPet: Cat | Dog = getPetSomehow(); if (isCat(myPet)) { myPet.purr(); // TypeScript knows `myPet` is a `Cat` here. } else { myPet.bark(); }
const myPet: Cat | Dog = getPetSomehow();

if (isCat(myPet)) {
    myPet.purr(); // TypeScript knows `myPet` is a `Cat` here.
} else {
    myPet.bark();
}

مثال دوم با کلاس

به طور مشابه می‌توانیم از type predicate به همراه کلاس استفاده کنیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
class Bird {
fly() { /*...*/ }
}
class Fish {
swim() { /*...*/ }
}
function isBird(pet: Bird | Fish): pet is Bird {
return (pet as Bird).fly !== undefined;
}
class Bird { fly() { /*...*/ } } class Fish { swim() { /*...*/ } } function isBird(pet: Bird | Fish): pet is Bird { return (pet as Bird).fly !== undefined; }
class Bird {
    fly() { /*...*/ }
}

class Fish {
    swim() { /*...*/ }
}

function isBird(pet: Bird | Fish): pet is Bird {
    return (pet as Bird).fly !== undefined;
}

احتیاط

مواردی که هنگام استفاده از type predicateها حتما باید به آن‌ها توجه داشته باشته باشیم عبارتند از:

جمع‌بندی