جواب کوتاه: برای شکل یک آبجکت یا کلاس، 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'.
این ویژگی — declaration merging — دلیل اصلی است که تایپهای کتابخانهها (مثل express یا خودِ DOM در lib.dom.d.ts) با interface نوشته میشوند: هر پکیج میتواند یک تعریف را گسترش بدهد، بدون اینکه تعریف اصلی را عوض کند.
type کاری بلد است که interface نه: یونیون
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 |
کاری که فقط type بلد است: نگاشت روی کلیدها
tstype Flags = { a: boolean; b: boolean };
type OptionalFlags = { [K in keyof Flags]?: Flags[K] };
این «mapped type» با موفقیت کامپایل میشود، ولی همین نحو روی interface اصلاً syntax معتبر نیست — کامپایلر همانجا با «] expected» متوقف میشود. اینجا هم همان قانون است: هر چیزی که از روی یک تایپ دیگر ساخته میشود (union، mapped، conditional)، فقط با type قابل نوشتن است؛ interface فقط یک شکل ثابت را توصیف میکند.
اگر تیمتان یکی از این دو را بهعنوان استاندارد انتخاب کرده، همان را دنبال کنید — ثباتِ سبک مهمتر از برتری فنی جزئی است. اگر تازه با TypeScript شروع کردهاید، دورهی TypeScript این تصمیمها را با پروژهی واقعی جا میاندازد.





نظرها
اولین نفری باشید که نظر میدهدسؤالتان را بپرسید یا تجربهتان را بنویسید — نویسندهی مطلب پاسخ میدهد.