Интерфейсы
Есть и второй способ описать форму объекта: интерфейс (interface).
interface Monster {
name: string;
health: number;
}Он означает то же самое, что type Monster = { name: string; health: number };. Вы используете Monster в аннотациях точно так же, и сообщения об ошибках те же. Отличается только запись: после interface идёт имя, а сразу за ним — фигурные скобки, без =. Обычно каждое свойство пишут на отдельной строке.
Особенно хорошо интерфейсы подходят для расширения (extending). Босс — это монстр с чем-то дополнительным, например с фазой боя. С помощью extends интерфейс Boss получает все свойства Monster (name и health) и добавляет свои:
interface Monster {
name: string;
health: number;
}
interface Boss extends Monster {
phase: number;
}
const wolf: Monster = { name: "волк", health: 30 };
const dragon: Boss = { name: "дракон", health: 300, phase: 1 };
function describe(monster: Monster): string {
return `${monster.name}: здоровье ${monster.health}`;
}
console.log(describe(wolf));
console.log(describe(dragon));
console.log(dragon);Программа выведет:
волк: здоровье 30
дракон: здоровье 300
{ name: "дракон", health: 300, phase: 1 }Общие свойства вы пишете только один раз. А когда у Monster появляется новое свойство, оно появляется и у Boss.
Обратите внимание: describe принимает Monster, и ей можно передать дракона. У босса есть всё, что есть у монстра, значит, он тоже монстр. В обратную сторону это не работает: монстр — не босс, ведь у него нет фазы:
interface Monster {
name: string;
health: number;
}
interface Boss extends Monster {
phase: number;
}
function describeBoss(boss: Boss): string {
return `${boss.name}, фаза ${boss.phase}`;
}
const wolf: Monster = { name: "волк", health: 30 };
console.log(describeBoss(wolf));main.ts(15,26): error TS2741: Property 'phase' is missing in type 'Monster' but required in type 'Boss'.type или interface? Для формы объекта подходят оба, и в настоящем коде вы встретите оба. Многие команды используют interface для объектов, а type — для всего остального, например для типов функций из урока «Функции» или для объединений из следующего урока, которые вообще нельзя записать как интерфейс. В этом курсе используются оба.
Типичные ошибки:
- Знак
=после имени, как уtype:
interface Monster = {
name: string;
health: number;
}main.ts(1,19): error TS1005: '{' expected.- Объект босса без дополнительного свойства:
Property 'phase' is missing in type '{ name: string; health: number; }' but required in type 'Boss'.
Задание
- 1
Перепишите
Characterкак интерфейс, каждое свойство на отдельной строке. - 2
Создайте интерфейс
Hero, который расширяетCharacterи добавляет два свойства:heroClassтипаstringиgoldтипаnumber. Затем под хозяйкой таверны создайтеkiraтипаHero: Кира, уровень 3,"следопыт", 120 золота. - 3
Замените строку с
console.logфункциейintroduce, которая принимаетCharacterи возвращает его текст, напримерЭма, уровень 1. Выведитеintroduce(innkeeper)иintroduce(kira): Кира — герой, а значит, и персонаж. Программа выведет:Эма, уровень 1 Кира, уровень 3