Типизация объектов и интерфейсы
Описываем форму объекта и даём ей имя через interface.
interface — именованное описание формы объекта: какие у него есть свойства и какого они типа.
Встроенный тип объекта
Форму объекта можно описать прямо в аннотации, перечислив свойства:
let user: { name: string; age: number } = {
name: "Аня",
age: 30,
};
user.age = "много"; // Ошибка: Type 'string' is not assignable to type 'number'.
user.email = "..."; // Ошибка: Property 'email' does not exist.
Теперь объект защищён: нельзя ни испортить тип свойства, ни добавить лишнее поле. Но писать такой тип в каждом месте — громоздко и легко рассинхронизировать.
interface — имя для формы
Чтобы переиспользовать описание, его выносят в interface. Это контракт, на который можно ссылаться по имени:
interface User {
name: string;
age: number;
}
const anya: User = { name: "Аня", age: 30 };
function printUser(u: User): void {
console.log(u.name + ", " + u.age);
}
Теперь тип User используется и в переменных, и в параметрах функций. Изменили интерфейс в одном месте — изменения подхватились везде. Имена интерфейсов по соглашению пишут с большой буквы.
Лишние и недостающие свойства
Объект должен точно соответствовать интерфейсу — ни больше, ни меньше:
const a: User = { name: "Боря" };
// Ошибка: Property 'age' is missing.
const b: User = { name: "Вера", age: 25, city: "Уфа" };
// Ошибка: Object literal may only specify known properties, and 'city' does not exist in type 'User'.
Это и есть польза: интерфейс гарантирует, что у объекта есть ровно нужные поля. Опечатка в имени свойства или забытое поле — ошибка компиляции, а не тихий undefined в рантайме.
Зачем это на практике
Интерфейсы описывают данные, которые ходят через всё приложение: ответы API, модели сущностей, пропсы компонентов. Когда форма данных зафиксирована, редактор подсказывает доступные поля, а рефакторинг (переименовали поле) подсвечивает все места, где нужно поправить код.
interface Product {
id: number;
title: string;
price: number;
inStock: boolean;
}
function describe(p: Product): string {
const status = p.inStock ? "в наличии" : "нет на складе";
return p.title + " — " + p.price + " руб. (" + status + ")";
}
Итог
- Форму объекта можно описать встроенно (
{ name: string }) или вынести вinterface. interface— переиспользуемый именованный контракт для структуры данных.- Объект обязан точно соответствовать интерфейсу: нет лишних и недостающих свойств, опечатки ловятся компилятором.