Короткий ответ: в интерфейсе TypeScript тип поля указывают после двоеточия: name: string, age: number, isActive: boolean. Если поле необязательное, добавляют ?: description?: string. Если поле нельзя менять, используют readonly
Пример:
interface User {
id: number;
email: string;
isActive: boolean;
}
Теперь объект User должен иметь все три поля с правильными типами
Необязательные поля
interface Article {
id: number;
title: string;
description?: string;
}
Поле description можно не указывать:
const article: Article = {
id: 1,
title: "TypeScript",
};
При чтении учитывайте, что оно может быть undefined
readonly
interface Product {
readonly id: number;
title: string;
price: number;
}
Теперь после создания нельзя просто переписать id:
product.id = 2;
TypeScript покажет ошибку
Union-тип в интерфейсе
interface Task {
id: number;
title: string;
status: "todo" | "in_progress" | "done";
}
Так вы ограничиваете допустимые значения. Ошибка вроде status: "finished" будет поймана заранее
Методы и функции
interface Logger {
log(message: string): void;
error(message: string, code?: number): void;
}
Или через поле-функцию:
interface ButtonProps {
label: string;
onClick: () => void;
}
Для React props второй вариант часто удобен
Вложенные объекты
interface UserProfile {
id: number;
name: string;
address: {
city: string;
street: string;
};
}
Если address нужен в нескольких местах, вынесите:
interface Address {
city: string;
street: string;
}
interface UserProfile {
id: number;
name: string;
address: Address;
}
Наследование интерфейсов
interface BaseEntity {
id: number;
}
interface User extends BaseEntity {
email: string;
}
User теперь обязан иметь и id, и email
Индексные поля
Если заранее неизвестны все ключи, можно описать индексную сигнатуру:
interface StringDictionary {
[key: string]: string;
}
const labels: StringDictionary = {
save: "Сохранить",
cancel: "Отмена",
};
Если значения могут быть разными, используйте union:
interface Settings {
[key: string]: string | number | boolean;
}
Но не злоупотребляйте индексными сигнатурами. Если поля известны, лучше перечислить их явно: TypeScript сможет проверить объект точнее
Когда лучше type, а не interface
Интерфейс хорошо подходит для формы объекта. Но если нужно описать union, используйте type:
type Status = "new" | "paid" | "cancelled";
А потом вставляйте его в интерфейс:
interface Order {
id: number;
status: Status;
}
Так код остается читаемым: интерфейс описывает объект, а type хранит набор допустимых значений
Частые ошибки
Первая ошибка — ставить = вместо ::
interface User {
id = number;
}
Правильно:
interface User {
id: number;
}
Вторая ошибка — делать все поля optional без причины. Тогда интерфейс почти ничего не гарантирует
Третья ошибка — использовать String, Number, Boolean вместо string, number, boolean. В обычных типах используйте нижний регистр
Четвертая ошибка — забыть тип функции и написать onClick: Function. Лучше указать конкретную сигнатуру
Пятая ошибка — использовать индексную сигнатуру там, где нужен конкретный интерфейс. Это делает тип слишком широким и скрывает опечатки в названиях полей
Самопроверка
Создайте интерфейс Order с readonly id, amount: number, status: "new" | "paid". Попробуйте поменять id и поставить status: "done". TypeScript должен показать ошибки
Что почитать дальше по TypeScript
Если нужен общий маршрут по теме, откройте рубрику TypeScript. Для соседних задач пригодятся эти разборы:
- 10 вопросов по TypeScript и ответы на них
- Any, unknown, never и strict
- App.tsx: что это за файл и как добавить TypeScript в React
- Conditional types в TypeScript: как работает extends



