Тип объекта
Чему вы научитесь:
- описывать форму объекта типом вроде
{ name: string; age: number }; - давать типу имя через
typeи читать ошибки о недостающем свойстве; - объявлять необязательные свойства и проверять их перед использованием;
- запрещать запись в свойство через
readonlyи знать, где эта защита кончается.

Представьте бумажную анкету. На ней заранее напечатаны поля: «Имя», «Возраст». Сотрудник, который принимает анкету, проверяет две вещи: все ли поля заполнены и то ли в них написано. Если в поле «Возраст» стоит слово, а не число, анкету вернут на исправление.
В JavaScript такой проверки нет. Функция получает объект и надеется, что в нём есть нужные свойства. Если свойства нет, она молча получит undefined, и ошибка всплывёт позже, далеко от места, где её сделали.
В TypeScript у объекта есть своя анкета — тип объекта: список имён свойств и тип каждого из них. Компилятор сверяет с ним каждый объект, который вы передаёте:
function describe(user: { name: string; age: number }) {
return `${user.name}, ${user.age}`;
}
console.log(describe({ name: "Ann", age: 30 })); // Ann, 30Давайте разберём пример по строкам:
- У параметра
userтип{ name: string; age: number }: в объекте должны быть свойствоnameсо строкой и свойствоageс числом. - Внутри функции TypeScript знает форму
user, поэтомуuser.nameдля него —string, аuser.age—number. - Вызов передаёт объект, который подходит под анкету, и программа печатает
Ann, 30.
Как записать тип объекта
Тип объекта похож на сам объект, только справа от двоеточия стоят типы, а не значения. Разберём запись { name: string; age: number } по частям:
- фигурные скобки открывают и закрывают описание формы;
name— имя свойства;- двоеточие и
string— тип значения в этом свойстве; - точка с запятой отделяет свойства друг от друга; запятая тоже допустима, но в типах принято ставить точку с запятой.
Сравните две записи. { name: "Ann" } — объект со значением, он существует, пока работает программа. { name: string } — тип, описание формы: его видит только компилятор, и в JavaScript-файл он не попадёт.
Для объектного литерала TypeScript выводит тип сам. Например, после const user = { name: "Ann", age: 30 } редактор покажет у user тип { name: string; age: number; }, если навести на него курсор. Писать тип вручную приходится там, где выводить его не из чего, и чаще всего это параметр функции.
Не хватает свойства
Компилятор сверяет объект с анкетой целиком. Если обязательного свойства нет, он сообщает, какого именно:
const user: { name: string; age: number } = { name: "Ann" }; // ✗error TS2741: Property 'age' is missing in type '{ name: string; }' but required in type '{ name: string; age: number; }'.Сообщение читается так: в типе { name: string; } нет свойства age, а в типе { name: string; age: number; } оно обязательно. Первый тип — это ваш литерал, каким его увидел TypeScript, второй — анкета из аннотации.
Если свойство на месте, но значение не того типа, ошибка будет другой — TS2322. Например, age: "30" не пройдёт: компилятор напишет, что строку нельзя присвоить типу number.
Здесь аналогия с анкетой перестаёт работать. Сотрудник смотрит и на сами ответы, а TypeScript проверяет только типы: возраст -5 он пропустит, ведь это число.
Опечатка в имени
Анкета защищает и при чтении: свойство, которого нет в типе, прочитать нельзя.
const user: { name: string; age: number } = { name: "Ann", age: 30 };
console.log(user.nmae); // ✗error TS2339: Property 'nmae' does not exist on type '{ name: string; age: number; }'.В JavaScript эта строка напечатала бы undefined, и опечатку пришлось бы искать по странному выводу. TypeScript показывает её сразу и на той строке, где она сделана.
Частая ошибка
Параметру дали тип object, чтобы сказать «сюда передают объект»:
function greet(user: object) {
return `Hi, ${user.name}`; // ✗
}
console.log(greet({ name: "Ann" }));error TS2339: Property 'name' does not exist on type 'object'.Тип object значит «какой-то объект» и ничего не говорит о его свойствах. Это анкета без единого поля: по ней нельзя прочитать ни имя, ни возраст. Перечислите свойства, которые нужны функции: user: { name: string }.
Главное
- Тип объекта перечисляет свойства и их типы:
{ name: string; age: number }. - Для объектного литерала TypeScript выводит такой тип сам, а у параметра функции его пишут вручную.
- Нет обязательного свойства — ошибка
TS2741; чтение свойства, которого нет в типе, — ошибкаTS2339. - Тип
objectне называет свойств, поэтому читать их через него нельзя.