Интерфейсы vs Типы в TypeScript
В чем разница между этими двумя объявлениями (interface
и type
) в TypeScript?
interface X {
a: number
b: string
}
type X = {
a: number
b: string
};
3 ответ(ов)
По состоянию на TypeScript 3.2 (ноябрь 2018 года) следующие утверждения верны:
Аспект | Type | Interface |
---|---|---|
Могут описывать функции | ✅ | ✅ |
Могут описывать конструкторы | ✅ | ✅ |
Могут описывать кортежи | ✅ | ✅ |
Интерфейсы могут их наследовать | ⚠️ | ✅ |
Классы могут их наследовать | 🚫 | ✅ |
Классы могут реализовывать их (implements ) |
⚠️ | ✅ |
Могут пересекаться с другим типом | ✅ | ⚠️ |
Могут объединяться с другим типом | ✅ | 🚫 |
Можно использовать для создания отображаемых типов | ✅ | 🚫 |
Можно отображать с помощью отображаемых типов | ✅ | ✅ |
Расширяются в сообщениях об ошибках и логах | ✅ | 🚫 |
Можно дополнительно определять | 🚫 | ✅ |
Могут быть рекурсивными | ⚠️ | ✅ |
⚠️ В некоторых случаях.
Примеры с Типами:
// создаем структуру дерева для объекта. Это невозможно сделать с помощью интерфейса из-за отсутствия пересечений (&)
type Tree<T> = T & { parent: Tree<T> };
// тип для ограничения переменной только несколькими значениями. У интерфейсов нет объединений (|)
type Choice = "A" | "B" | "C";
// благодаря типам вы можете объявить тип NonNullable с помощью условного механизма.
type NonNullable<T> = T extends null | undefined ? never : T;
Примеры с Интерфейсами:
// вы можете использовать интерфейс для ООП и использовать 'implements' для определения структуры объекта/класса
interface IUser {
user: string;
password: string;
login: (user: string, password: string) => boolean;
}
class User implements IUser {
user = "user1";
password = "password1";
login(user: string, password: string) {
return (this.user === user && this.password === password);
}
}
// вы можете расширять интерфейсы другими интерфейсами
interface IMyObject {
label: string;
}
interface IMyObjectWithSize extends IMyObject {
size?: number;
}
В TypeScript предпочтительнее использовать "interface" вместо "type" по нескольким причинам:
Псевдонимы типов: "type" используется для создания псевдонимов типов. Это невозможно сделать с помощью "interface".
type Data = string;
Теперь вместо использования
string
вы можете использовать "Data":const name: string = "Yilmaz"; const name: Data = "Yilmaz";
Псевдонимы типов очень полезны, особенно при работе с обобщёнными типами.
Слияние деклараций: Вы можете объединять интерфейсы, но не типы.
interface Person { name: string; } interface Person { age: number; } // Здесь необходимо предоставить свойства для обоих интерфейсов const me: Person = { name: "Yilmaz", age: 30 };
Предпочтения в программировании: Пользователи функционального программирования чаще используют "type", в то время как пользователи объектно-ориентированного программирования выбирают "interface".
Вычисляемые свойства: Вы не можете иметь вычисляемые или рассчитанные свойства в интерфейсах, но это возможно с типами.
type Fullname = "firstname" | "lastname"; type Person = { [key in Fullname]: string; }; const me: Person = { firstname: "Yilmaz", lastname: "Bingol" };
В общем, если у вас есть возможность выбора, рекомендуется использовать "interface", так как они предлагают больше возможностей и гибкости в типизации.
Как явно задать новое свойство у `window` в TypeScript?
Как преобразовать строку в число в TypeScript?
Как конвертировать строку в enum в TypeScript?
Как удалить элемент массива в TypeScript?
'unknown' против 'any': в чем разница?