TypeScript позволяет определять типы отдельно от переменных, которые их используют.
Псевдонимы типов и интерфейсы позволяют легко обмениваться типами между разными переменными и объектами.
Псевдонимы типов
Псевдонимы типов позволяют создавать собственные имена для существующих типов данных.
Псевдонимы типов могут применяться как к примитивным типам (например, string), так и к более сложным структурам, таким как объекты и массивы:
Пример
type CarYear = number;
type CarType = string;
type CarModel = string;
type Car = {
year: CarYear,
type: CarType,
model: CarModel
};
const carYear: CarYear = 2001;
const carType: CarType = "Toyota";
const carModel: CarModel = "Corolla";
const car: Car = {
year: carYear,
type: carType,
model: carModel
};
Пример: объединение и пересекающиеся типы
type Animal = { name: string };
type Bear = Animal & { honey: boolean }; // Пересечение типов
const bear: Bear = { name: "Winnie", honey: true };
type Status = "success" | "error"; // Объединение типов
let response: Status = "success";
Интерфейсы
Интерфейсы похожи на псевдонимы типов, но предназначены только для объектов (тип object).
Пример
interface Rectangle {
height: number;
width: number;
}
const rectangle: Rectangle = {
height: 20,
width: 10
};
Пример: объединение интерфейсов
interface Animal { name: string; }
interface Animal { age: number; } // Совместимы, дополняя друг друга
const dog: Animal = { name: "Fido", age: 5 };
Типы vs Интерфейсы: главные различия
- Расширение: Оба могут быть расширены, но интерфейсы поддерживают декларативное объединение.
- Объединения/пересечения: Только псевдонимы типов поддерживают объединение и пересечение типов.
- Реализация: Классы могут реализовывать как интерфейсы, так и псевдонимы типов.
Лучшая практика:
- Используйте интерфейсы для описания форматов объектов и публичных API.
- Используйте псевдонимы типов для объединений, пересечений и примитивных типов.
- Предпочитайте композицию наследованию при работе с типами.
- Документирование типов и интерфейсов повышает ясность.
Распространённые ловушки:
- Использование псевдонима типа, когда требуется декларативное объединение (лучше использовать интерфейс).
- Перегрузка типов, делайте их простыми и целенаправленными.
- Забывание обновлять типы/интерфейсы при изменении кода.
Расширение интерфейсов
Интерфейсы могут расширять друг друга.
Расширение интерфейса означает, что вы создаете новый интерфейс с теми же свойствами, что и в оригинальном, но при этом вы добавляете новые свойства.
Пример
interface Rectangle {
height: number;
width: number;
}
interface ColoredRectangle extends Rectangle {
color: string;
}
const coloredRectangle: ColoredRectangle = {
height: 20,
width: 10,
color: "red"
};
Таким образом, TypeScript предоставляет мощные инструменты для организации и унификации типов, позволяя строить гибкие и масштабируемые проекты.