Стендап Сьогодні 📢 Канал в Telegram @stendap_sogodni
🤖🚫 AI-free content. This post is 100% written by a human, as is everything on my blog. Enjoy!30.11.2023
Типи та інтерфейси в TypeScript - в чому різниця?
Деякий час мене турбує питання — як це так, що в TypeScript можна створювати однакові типи як словом type
, так і interface
? Згадав про це з довідника по TS, в якому відповіді немає, зате багато чого цікавого є.
// виглядає ніби однаково
type T = { foo: string };
interface I {
bar: number;
}
// і ніби використовується однаково:
interface E extends T, I {
baz: boolean;
}
Так в чому різниця? В інтернеті можна знайти функціональне пояснення, тобто яка різниця у використанні, але мені більше цікавий сенс існування обох синтаксисів. Розібрався.
Типи в TypeScript, взагалі, не мають назв. Будь-яке значення має тип; він або задається явно, або виводиться з оточення. Якщо ми хочемо привʼязати до типу назву, то вживаємо ключове слово type
, і оголошуємо псевдонім типу. Псевдонімом можна назвати будь-який тип, незалежно від складності.
Інтерфейс — це один з різновидів типів. А саме, це тип, який описує обʼєкт. Для перевірки типів що безіменний тип, що названий, що інтерфейс — абсолютно еквівалентні. Для успадкування теж практично байдуже, хіба що безіменний тип не можна успадкувати.
Є лише одна функція, доступна тільки через інтерфейс, оголошений словом interface
. Це розширення інтерфейсу. Якщо оголосити інтерфейс з однаковим імʼям два рази, то типи будуть обʼєднані в один. Такий трюк особливо важливий для бібліотек, бо традиційно в JavaScript заведено підсипати функціонал до обʼєктів, які вже існують — на кшталт window.jQuery
. Про це я вже писав. Причому, типи так само можна розширювати, але не під тою самою назвою. Але в межах одного проєкту це не тільки прийнятно, а навпаки — бажано.
Виходить, що оголошення interface
утворює точку розширення, в цьому його сенс. Оскільки іншої різниці реально немає, то я б використовував interface
тільки саме з цим наголосом.