بیشترین سوالات پرسیده شده از تایپ اسکریپت در stackoverflow و پاسخ آن‌ها - قسمت اول

تا حالا هیچ دولوپری نگفته «من از stackoverflow متنفرم»

در حالی که شما تنها یک سرچ گوگل با پیدا کردن جواب فاصله دارید، حقیقتاً درک درست راه حل برای شما مهم‌ترین بخش است.

در این سری مقالات می‌خواهیم ۷ سوال پر تکرار در stackoverflow درباره تایپ‌اسکریپت را بررسی کنیم.

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

با این مقالات امیدوارم که به درک عمیق‌تری از مسائلی که ممکن است با تایپ‌اسکریپت مواجه شوید، برسید.

اگر به تازگی شروع به یادگیری تایپ‌اسکریپت کرده‌اید، این موضوع نیز مرتبط است و چه راهی بهتر از آشنایی با چالش های آینده خود!

چه تفاوتی بین Interfaces و Types در تایپ‌اسکریپت وجود دارد؟

تفاوت interfaces و types در تایپ‌اسکریپت
تفاوت interfaces و types در تایپ‌اسکریپت

درواقع Interface و Type که نوع تایپی هستند، یک رقابت تنگاتنگی باهم دارند.

وقتی که شروع به یادگیری تایپ‌اسکریپت می‌کنید، ممکن است انتخاب بین این دو برای شما مشکل و گیج کننده باشد. این مقاله سردرگمی شما را برطرف خواهد کرد و به شما کمک می‌کند تا انتخاب مناسبی داشته باشید.

در نمونه‌های زیادی، شما می‌توانید Interface و یا Type را بجای یکدیگر استفاده کنید.

تقریباً تمام فیچرهای Interface در type نیز در دسترس است، بجز اینکه شما نمی‌توانید پراپرتی جدیدی در Type با استفاده از re-declaring اضافه کنید. شما حتماً باید یک intersection type استفاده کنید.

چرا از همان ابتدا درباره Type و Interface گیج می‌شویم؟

هر زمان که ما با گزینه‌های متعددی برای انتخاب مواجه می‌شویم، اکثر مردم از تضاد انتخاب رنج می‌برند.

اما خوشبختانه در این مورد خاص، فقط دو گزینه وجود دارد.

نکته‌ی اصلی گیج کننده در اینجا و بین این دو گزینه این است که در اکثر موارد به طور مساوی شبیه به هم هستند و تطابق دارند.

و این کار را برای یک انتخاب مشخص سخت می‌کند، مخصوصاً وقتی که تازه شروع به کار با تایپ‌اسکریپت می‌کنید.

یک مثال ساده از Type و Interface

تعریف کردن یک تایپ Human را در نظر بگیرید:

// type 
type Human = {
  name: string 
  legs: number
  head: number
}
// interface 
interface Human {
   name: string 
   legs: number 
   head: number
}


هر دو روش برای تعریف تایپ‌ Human با استفاده از Type و Interface درست است.

تفاوت‌های بین Type و Interface

تفاوت کلیدی: Interface فقط می‌تواند شکل آبجکت (object shape) را توصیف کند. اما Type برای تایپ‌های دیگر مانند primitives, unions و tuplesها می‌تواند استفاده شود.

تعریف متغیر با Type در انواع داده‌هایی که می‌توانید نمایش دهید کاملاً انعطاف‌پذیر است. از primitiveهای اولیه unionهای پیچیده و tuplesها، همانطور که در بخش زیر نشان داده شده است:

// primitives
type Name = string
// object
type Male = {
   name: string
}
type Female = {
    name: string
}
// union
type HumanSex = Male | Female
// tuple
type Children = [Female, Male, Female]

بر خلاف Type، شما برای تعریف تایپ‌های یک آبجکت فقط باید از Interface استفاده کنید.

تفاوت کلیدی:‌ یک Interface را می‌توان با چندین بار اعلام (declare) آن گسترش داد.

مثال زیر را در نظر بگیرید:

interface Human {
   name: string 
}
interface Human {
    legs: number
}


دو اعلام (declaration) بالا، به شکل زیر تغییر می‌تواند باشد:

interface Human {
    name: string 
    legs: number 
}

در اینجا Human را می‌توان با یک interface تعریف کرد: ترکیبی از اعضای هر دو اعلام

پراپرتی legs برای آبجکت Human الزامی است.
پراپرتی legs برای آبجکت Human الزامی است.

مشاهده در Typescript Playground

در صورتی که همچین مدل تعریف کردن در Type امکان‌پذیر نیست و باعث بوجود آمدن پیغام خطا می‌شود.

type Human = {
    name: string
}
type Human =  {
     legs: number 
}
const h: Human = {
     name: 'gg',
     legs: 5 
}  
آبجکت Human دوبار تعریف شده است
آبجکت Human دوبار تعریف شده است

مشاهده در Typescript Playground

برای نوشتن همچین چیزی با استفاده از Type، باید آن‌ها را بهم متصل کنیم:

type HumanWithName = {
    name: string 
}
type HumanWithLegs =  {
    legs: number 
}
type Human  = HumanWithName & HumanWithLegs
const h: Human = {
   name: 'gg',
   legs: 5 
}  

مشاهده در Typescript Playground

تفاوت جزئی: هردو Type و Interface قابلیت تعمیم (extend) دارند، اما با syntaxهای متفاوت

با Interface شما باید از کلمه کلیدی extends استفاده کنید. اما برای Type، شما باید از یک اتصال دهنده استفاده کنید.

به مثال‌های زیر توجه کنید:

تعمیم دادن یک Type با Typeای دیگر

type HumanWithName = {
  name: string 
}
type Human = HumanWithName & {
   legs: number 
   eyes: number 
}

تعمیم دادن یک Type با Interface

interface HumanWithName {
  name: string 
}
type Human = HumanWithName & {
   legs: number 
   eyes: number 
}

تعمیم دادن یک Interface با Interface

interface HumanWithName {
  name: string
}
interface Human extends HumanWithName {
  legs: number 
  eyes: number 
}

تعمیم دادن یک Interface با یک Type

type HumanWithName = {
  name: string
}
interface Human extends HumanWithName {
  legs: number 
  eyes: number 
}

همانطور که در مثال‌های بالا مشاهده می‌کنید، هیچ دلیل منحصر به فردی برای ترجیح دادن یکی به دیگری وجود ندارد. هرچند که syntaxهای آن‌ها متفاوت است.

تفاوت جزئی: کلاس‌ها فقط می‌توانند اعضای شناخته شده را به صورت استاتیک پیاده سازی کنند.

یک کلاس می‌تواند Interface و یا Type را پیاده‌سازی کند. هرچند که یک کلاس نمی‌تواند یک تایپ union را پیاده‌سازی و یا گسترش دهد.

به مثال‌های زیر توجه کنید:

پیاده‌سازی کلاس با Interface

interface Human {
  name: string
  legs: number 
  eyes: number 
}
class FourLeggedHuman implements Human {
  name = 'Krizuga'
  legs = 4
  eyes = 2
}

پیاده‌سازی کلاس با Type

type Human = {
  name: string
  legs: number 
  eyes: number 
}
class FourLeggedHuman implements Human {
  name = 'Krizuga'
  legs = 4
  eyes = 2
}

هردوی این‌ها به خوبی و بدون خطا کار می‌کنند، هرچند در مثال زیر به خطا میخورد:

پیاده سازی کلاس با union

type Human = {
     name: string
} | {
    legs: number
    eyes: number
}
class FourLeggedHuman implements Human {
    name = 'Krizuga'
    legs = 4
    eyes = 2
}
A class can only implement an object type or intersection of object types with statically known members.
A class can only implement an object type or intersection of object types with statically known members.

مشاهده در Typescript Playground

جمع‌بندی Type در مقابل Interface

برداشت شما ممکن است متفاوت باشد، اما هرجا که ممکن است، من به Type چسبیده‌ام، بخاطر انعطاف‌پذیری و syntax ساده‌ای که دارد. همین، من Type را انتخاب می‌کنم، بجز هرجای بخصوصی که به Interface بخاطر خاصیت‌هایش نیاز داشته باشم.

برای بیشتر قسمت‌ها، همینطور شما‌ می‌توانید بر اساس ترجیح شخصی‌تان تصمیم بگیرید، اما باید بر انتخاب‌تان استوار باشید، حداقل بر روی یک پروژه.

برای کامل شدن، من باید مقایسه پرفورمنس بین Type و Interface را اضافه کنم، تا ببینیم کدام سریع‌تر است. هرچند این به عنوان یک مشکل برای من باقی مانده است.

عناوین مقاله‌های آینده

  1. In TypeScript, what is the ! (exclamation mark / bang) operator?
  2. What is a “.d.ts” file in TypeScript?
  3. How Do You Explicitly Set a New Property on ‘window’ in TypeScript?
  4. Are Strongly Typed Functions as Parameters Possible in TypeScript?
  5. How to Fix Could Not Find Declaration File for Module …?
  6. How Do I Dynamically Assign Properties to an Object in TypeScript?

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