سلام دوستان! توی تایپ‌اسکریپت یه ویژگی داریم به اسم Type Predicate که هدف اون بهبود Type Narrowing هست. ابتدا با معنی Narrowing آشنا بشیم:

 

Narrowing چیه؟ 🤔

معنی واژه Narrowing یعنی محدود کردن یا باریک کردن. تایپ‌اسکریپت با عملیات Narrowing کاری می‌کنه که نوعِ یک مقدار به شکل خاص‌تر و مشخص‌تر برای ما در دسترس باشه.

توی عکس همونطور که می‌بینیم، پارامتر x ممکنه رشته باشه یا عدد:

تصویر نوشته

توی این کد دو عملیات Narrowing انجام گرفته: یکی برای بلاک if و یکی هم برای else. با این ویژگی، با پارامتر x توی بلاک if فقط به صورت رشته رفتار میشه. برای مثال اگه متد toFixed رو صدا بزنیم خطا می‌گیریم. چون توی این بلاک، x فقط به صورت رشته قابل دسترس هست. همچنین توی بلاک else تایپ‌اسکریپت می‌دونه که نوع x دیگه رشته نیست و قطعاً عددی هست. پس با اون مثل یک عدد رفتار می‌کنه.

 

خب حالا بریم که موضوع اصلی این پست رو بررسی کنیم. توی تایپ‌اسکریپت اگه چنین کدی داشته باشیم:

function isString(value: any) {
  return typeof value === 'string';
}

const value = Math.random() < 0.5 ? "string" : 10;


if (isString(value)) {
  console.log('value is a string', <<value.length>>);
} else {
  console.log('value is not a string', value);
}

کامپایلر تایپ‌اسکریپت توی خط ۹ بهمون خطا میده که:

Property 'length' does not exist on type '"string" | 10'

برای اجرای این کد می‌تونین رو ببینین. این خطا به این معنی هست که تایپ‌اسکریپت توی خط ۹ نتونسته نوع متغیر value رو تشخیص بده و به قول معروف Narrowing انجام بده. یک راه خوب برای حل چنین مشکلی اینه که از یک تکنیک به اسم Type Predicates استفاده کنیم:

function isString(value: any): <<value is string>> {
  return typeof value === 'string';
}

const value = Math.random() < 0.5 ? "string" : 10;

if (isString(value)) {
  console.log('value is a string', value.length);
} else {
  console.log('value is not a string', value);
}