تفاوت interface و type در TypeScript؛ کِی از کدام استفاده کنیم؟
آموزش

تفاوت interface و type در TypeScript؛ کِی از کدام استفاده کنیم؟

تفاوت interface و type سلیقه نیست؛ interface را برای آبجکت‌هایی بگیرید که بعداً گسترش پیدا می‌کنند و type را برای یونیون و نگاشت روی کلیدها.

تحریریه‌ی دینا کد
نویسنده
۳ دقیقه مطالعه۴ بازدید
اشتراک گذاری۴
فهرست مطالب
  1. ۱interface را می‌شود دوباره تعریف کرد، type را نه
  2. ۲یونیون فقط با type ساخته می‌شود
  3. ۳extends در interface، & در type
  4. ۴قانون عملی
  5. ۵mapped type فقط با type ممکن است

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

interface را می‌شود دوباره تعریف کرد، type را نه

tsinterface User { name: string; }
interface User { age: number; }
const u: User = { name: 'سارا', age: 20 }; // درست کامپایل می‌شود
tstype User = { name: string };
type User = { age: number };
// error TS2300: Duplicate identifier 'User'.

دلیل اصلی اینکه تایپ‌های کتابخانه‌ها (مثل express یا خودِ DOM در lib.dom.d.ts) با interface نوشته می‌شوند همین declaration merging است؛ هر پکیج می‌تواند یک تعریف را گسترش بدهد بدون اینکه تعریف اصلی را عوض کند.

یونیون فقط با type ساخته می‌شود

tstype Status = 'draft' | 'published' | 'archived';
let s: Status = 'draft';
s = 'weird';
// error TS2322: Type '"weird"' is not assignable to type 'Status'.

هیچ interfaceـی نمی‌تواند یونیونِ رشته‌های ثابت را نشان بدهد؛ یونیون فقط با type تعریف می‌شود.

extends در interface، & در type

tsinterface Animal { name: string }
interface Dog extends Animal { breed: string }
tstype Animal = { name: string };
type Dog = Animal & { breed: string };

هر دو یک Dog می‌سازند که هم name دارد و هم breed؛ فقط نحوشان فرق دارد. برای این حالت ساده، فرقی در نتیجه نمی‌کند و اختلاف وقتی معنا می‌گیرد که به declaration merging یا یونیون نیاز داشته باشید.

قانون عملی

نیاز انتخاب
شکل یک آبجکت/کلاس که ممکن است بعداً گسترش پیدا کند interface
یونیون، تقاطع، تاپل، یا هر چیزی غیر از آبجکت ساده type
تایپ کتابخانه‌ای که دیگران باید بتوانند augment کنند interface

mapped type فقط با type ممکن است

tstype Flags = { a: boolean; b: boolean };
type OptionalFlags = { [K in keyof Flags]?: Flags[K] };

این «mapped type» بی‌دردسر کامپایل می‌شود، ولی همین نحو را روی interface بنویسید کامپایلر همان‌جا خطای error TS1005: ']' expected می‌دهد. اینجا هم همان قانون است: هر چیزی که از روی یک تایپ دیگر ساخته می‌شود (union، mapped، conditional) فقط با type قابل نوشتن است؛ interface فقط یک شکل ثابت را توصیف می‌کند.

اگر تیم‌تان یکی از این دو را به‌عنوان استاندارد انتخاب کرده، همان را دنبال کنید؛ ثباتِ سبک مهم‌تر از برتری فنی جزئی است. اگر تازه با TypeScript شروع کرده‌اید، دوره‌ی TypeScript این تصمیم‌ها را با پروژه‌ی واقعی جا می‌اندازد.

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

تحریریه‌ی دینا کد
نویسنده

نظرها

اولین نفری باشید که نظر می‌دهد
برای ثبت نظر وارد شوید

سؤالتان را بپرسید یا تجربه‌تان را بنویسید تا نویسنده‌ی مطلب پاسخ بدهد.

مطالب مرتبط

از همین دسته
دستور stash در گیت چیست و چه کاربردی دارد
آموزش

دستور stash در گیت چیست و چه کاربردی دارد

دستور stash در گیت تغییرات ثبت‌نشده شاخه کاری را موقتا کنار می‌گذارد تا بدون ثبت کامیت ناقص بتوانید روی وظایف فوری کار کنید.

تحریریه‌ی دینا کد۶ دقیقه
diff در گیت چیست و چه‌وقت استفاده می‌شود؟
آموزش

diff در گیت چیست و چه‌وقت استفاده می‌شود؟

git diff دو نسخه از کدها را کنار هم می‌گذارد و خط‌به‌خط نشان می‌دهد چه چیزی عوض شده. یک نگاه به diff قبل از هر add و commit کافی است

تحریریه‌ی دینا کد۷ دقیقه