تایپ اسکریپت یک زبان برنامه نویسی است که برنامه را قبل از اجرا، از نظر خطا بررسی می‌کند و این کار را بر اساس تایپ مقادیر انجام می‌دهد. همین موضوع آن را به یک type checker داینامیک تبدیل می‌نماید. نسخه ۵٫۵ تایپ اسکریپت به تازگی منتشر شده است. در این مقاله قصد داریم تا چهار ویژگی جدید که در نسخه ۵٫۵ به تایپ اسکریپت اضافه شده است را باهم بررسی کنیم.

بهبود Filtering آرایه

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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// v5.4
const array = [1, 2, 3, null]
// TypeScript still thinks numbers is (number | null)[]
// This means TypeScript still thinks our numbers array has null values
const numbers = array.filter(item => item != null)
numbers.forEach(number => {
// TypeScript will error here because it thinks number could be null
console.log(number + 1)
})
// v5.4 const array = [1, 2, 3, null] // TypeScript still thinks numbers is (number | null)[] // This means TypeScript still thinks our numbers array has null values const numbers = array.filter(item => item != null) numbers.forEach(number => { // TypeScript will error here because it thinks number could be null console.log(number + 1) })
// v5.4
const array = [1, 2, 3, null]

// TypeScript still thinks numbers is (number | null)[]
// This means TypeScript still thinks our numbers array has null values
const numbers = array.filter(item => item != null)

numbers.forEach(number => {
  // TypeScript will error here because it thinks number could be null
  console.log(number + 1)
})

وقتی به این کد نگاه می‌کنیم، واضح است که آرایه

numbers
numbers ما دیگر مقادیر
null
null ندارد، ولی تایپ اسکریپت آنقدر هوشمند نیست که بتواند این موضوع را بفهمد. اما همانطور که انتظار داریم این کد با نسخه ۵٫۵ تایپ اسکریپت  به درستی کار می‌کند.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// v5.5
const array = [1, 2, 3, null]
// TypeScript now knows that numbers is number[]
const numbers = array.filter(item => item != null)
numbers.forEach(number => {
// No errors
console.log(number + 1)
})
// v5.5 const array = [1, 2, 3, null] // TypeScript now knows that numbers is number[] const numbers = array.filter(item => item != null) numbers.forEach(number => { // No errors console.log(number + 1) })
// v5.5
const array = [1, 2, 3, null]

// TypeScript now knows that numbers is number[]
const numbers = array.filter(item => item != null)

numbers.forEach(number => {
  // No errors
  console.log(number + 1)
})

این کد حتی اگر تابع دیگری را به تابع

filter
filter خود منتقل کنیم یا منطق پیچیده‌تری داشته باشیم نیز کار خواهد کرد.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// v5.5
const people = [{ name: "Kyle", age: 27 }, { name: "John" }]
// TypeScript now knows that peopleWithAge is ({ name: string, age: number })[]
// This means TypeScript knows that peopleWithAge only has objects with an age and name property
const peopleWithAge = people.filter(person => person.age != null)
peopleWithAge.forEach(person => {
// No errors
console.log(`${person.name} will be ${person.age + 1} years old next year`)
})
// v5.5 const people = [{ name: "Kyle", age: 27 }, { name: "John" }] // TypeScript now knows that peopleWithAge is ({ name: string, age: number })[] // This means TypeScript knows that peopleWithAge only has objects with an age and name property const peopleWithAge = people.filter(person => person.age != null) peopleWithAge.forEach(person => { // No errors console.log(`${person.name} will be ${person.age + 1} years old next year`) })
// v5.5
const people = [{ name: "Kyle", age: 27 }, { name: "John" }]

// TypeScript now knows that peopleWithAge is ({ name: string, age: number })[]
// This means TypeScript knows that peopleWithAge only has objects with an age and name property
const peopleWithAge = people.filter(person => person.age != null)

peopleWithAge.forEach(person => {
  // No errors
  console.log(`${person.name} will be ${person.age + 1} years old next year`)
})

بهبود استنتاج Object Key

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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// v5.4
function upperCaseKey(obj: Record<string, unknown>, key: string) {
if (typeof obj[key] === "string") {
// Error: TypeScript still thinks obj[key] is unknown
return obj[key].toUpperCase()
}
}
// v5.4 function upperCaseKey(obj: Record<string, unknown>, key: string) { if (typeof obj[key] === "string") { // Error: TypeScript still thinks obj[key] is unknown return obj[key].toUpperCase() } }
// v5.4
function upperCaseKey(obj: Record<string, unknown>, key: string) {
  if (typeof obj[key] === "string") {
    // Error: TypeScript still thinks obj[key] is unknown
    return obj[key].toUpperCase()
  }
}

همانطور که در این کد می‌بینیم، ما تایپ

obj[key]
obj[key] را به یک رشته محدود کرده‌ایم، اما تایپ اسکریپت آنقدر هوشمند نیست که متوجه شود این تایپ در داخل بلاک
if
if محدود شده است. به همین دلیل است که در نسخه ۵٫۴ با خطا مواجه می‌شویم. برای برطرف کردن این مشکل باید یک متغیر جدید برای ذخیره تایپ محدود شده ایجاد کنیم.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// v5.4
function upperCaseKey(obj: Record<string, unknown>, key: string) {
const value = obj[key]
if (typeof value === "string") {
// No errors
return value.toUpperCase()
}
}
// v5.4 function upperCaseKey(obj: Record<string, unknown>, key: string) { const value = obj[key] if (typeof value === "string") { // No errors return value.toUpperCase() } }
// v5.4
function upperCaseKey(obj: Record<string, unknown>, key: string) {
  const value = obj[key]
  if (typeof value === "string") {
    // No errors
    return value.toUpperCase()
  }
}

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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// v5.5
function upperCaseKey(obj: Record<string, unknown>, key: string) {
if (typeof obj[key] === "string") {
// No errors
return obj[key].toUpperCase()
}
}
// v5.5 function upperCaseKey(obj: Record<string, unknown>, key: string) { if (typeof obj[key] === "string") { // No errors return obj[key].toUpperCase() } }
// v5.5
function upperCaseKey(obj: Record<string, unknown>, key: string) {
  if (typeof obj[key] === "string") {
    // No errors
    return obj[key].toUpperCase()
  }
}

بررسی Regular Expression

در نسخه‌های قبلی تایپ اسکریپت اگر یک عبارت منظم در کد خود داشتیم توسط type checker تایپ اسکریپت کاملاً نادیده گرفته می‌شد. این بدان معنی است که ما می‌توانیم یک عبارت منظم داشته باشید که نامعتبر باشد و تایپ اسکریپت چیزی در مورد آن نگوید. این موضوع دیگر در نسخه ۵٫۵ تایپ اسکریپت صدق نمی‌کند. زیرا، تایپ اسکریپت عبارات منظم را بررسی می‌کند تا به ما اطلاع دهد که آیا مشکلات احتمالی در آن‌ها وجود دارد یا خیر.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const regex1 = /extra(parens))?/
// Error: Unexpected ')'. Did you mean to escape it with backslash?
const regex2 = /capture(?<group>.+) \k<namedImport>/
// Error: There is no capturing group named 'namedImport' in this regular expression.
const regex1 = /extra(parens))?/ // Error: Unexpected ')'. Did you mean to escape it with backslash? const regex2 = /capture(?<group>.+) \k<namedImport>/ // Error: There is no capturing group named 'namedImport' in this regular expression.
const regex1 = /extra(parens))?/
// Error: Unexpected ')'. Did you mean to escape it with backslash?

const regex2 = /capture(?<group>.+) \k<namedImport>/
// Error: There is no capturing group named 'namedImport' in this regular expression.

این فقط یک نمونه کوچک از بسیاری از خطاهای مختلف است که تایپ اسکریپت اکنون می‌تواند با عبارات منظم دریافت کند.

متدهای جدید Set

آخرین ویژگی که می‌خواهیم در مورد آن صحبت کنیم متدهای جدیدی است که به کلاس

Set
Set اضافه شده است. تایپ اسکریپت در نسخه ۵٫۵ پشتیبانی از تمام متدهای جدید
Set
Set را که اخیراً در جاوااسکریپت معرفی شده‌اند را اضافه کرده است. این موارد شامل
intersection
intersection،
union
union،
difference
difference و همه متدهای دیگر می‌باشد.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const set1 = new Set([1, 2, 3])
const set2 = new Set([3, 4, 5])
const intersection = set1.intersection(set2)
const union = set1.union(set2)
const difference = set1.difference(set2)
const set1 = new Set([1, 2, 3]) const set2 = new Set([3, 4, 5]) const intersection = set1.intersection(set2) const union = set1.union(set2) const difference = set1.difference(set2)
const set1 = new Set([1, 2, 3])
const set2 = new Set([3, 4, 5])

const intersection = set1.intersection(set2)
const union = set1.union(set2)
const difference = set1.difference(set2)

این یک ویژگی بسیار مفید برای تایپ اسکریپت است. زیرا، این متدهای جدید

Set
Set واقعاً مفید هستند و اکنون می‌توانیم بدون هیچ مشکلی از آن‌ها در تایپ اسکریپت نیز بهره‌مند شویم.

جمع‌بندی

در این مقاله سعی کردیم تا چهار ویژگی جدید که در نسخه ۵٫۵ تایپ اسکریپت معرفی شده است را باهم بررسی کنیم. این نسخه تایپ اسکریپت ممکن است به‌روزرسانی کوچکی به نظر برسد، اما بهبودهای بسیار باکیفیتی را به همراه دارد.