Герой
Добро пожаловать на последний урок курса TypeScript! В нём вы соберёте всё, чему научились, и шаг за шагом напишете одну программу: инвентарь и журнал квестов Киры. Следопыт Кира носит с собой несколько предметов, использует часть из них в пути и ведёт список своих квестов. Когда вы закончите, программа выведет вот это:
Кира, следопыт, уровень 3, здоровье 34/50, золото 120
Инвентарь:
- Целебное зелье (лечит на 20)
- Серебряный меч (урон 12)
- Старый ключ (открывает склеп)
- Свиток света (заклинание: Свет)
Кира пьёт «Целебное зелье»: здоровье 50/50
Кира берёт в руку «Серебряный меч»
Кира не нашла предмет «Драконье яйцо»
Квесты:
[выполнено] Волки в лесу: золото +50
[активно] Потерянная корона
[провалено] Спасти мельника: мельница сгорела
[выполнено] Мост гоблинов: золото +30
Выполнено: 2, активно: 1, провалено: 1
Кира, следопыт, уровень 3, здоровье 50/50, золото 200Программа описывает Киру, перечисляет её предметы, использует два из них (зелье лечит её, а меч она берёт в руку), ищет предмет, которого у неё нет, просматривает её квесты, подсчитывает их и прибавляет награды к её золоту. Вы используете почти весь курс: аннотации типов, функции, интерфейсы, свойства только для чтения и необязательные, объединения литеральных типов, размеченные объединения с switch и проверкой полноты, find и undefined, обобщённую функцию с ограничением, Record и тип, взятый из другого типа. Каждое упражнение продолжает предыдущее (в редакторе лежит его готовый код) и добавляет одну часть.
План. В редакторе есть четыре комментария, которые делят программу на части. Сверху // Типы: типы описывают данные, с которыми работает программа, поэтому каждый, кто открывает программу, видит их первыми. Под ними // Функции, затем // Данные с Кирой (а позже и её квестами) и внизу // Основная программа, которая использует функции и выводит результат. Типы можно было бы разместить где угодно, ведь они исчезают до запуска программы. А вот kira нужно создать выше основной программы, которая её использует, потому что программа выполняется сверху вниз.
Первый шаг: герой. В этой игре герой принадлежит к одному из трёх классов. Список допустимых значений — это объединение литеральных типов из урока «Объединения и сужение типов». Герой — объект, поэтому для него нужен interface, как в уроке «Типы объектов». Например, монстр и его сложность:
type Difficulty = "лёгкий" | "обычный" | "трудный";
interface Monster {
readonly name: string;
difficulty: Difficulty;
health: number;
}
function describeMonster(monster: Monster): string {
return `${monster.name} (${monster.difficulty}), здоровье ${monster.health}`;
}
const troll: Monster = { name: "Тролль", difficulty: "трудный", health: 80 };
console.log(describeMonster(troll));Это выведет:
Тролль (трудный), здоровье 80Имя Киры в ходе приключения не изменится, поэтому сделайте его readonly. Тогда TypeScript сообщит о каждой строке, которая попытается его изменить: Cannot assign to 'name' because it is a read-only property. Здоровье, золото и уровень Киры будут меняться, так что это обычные свойства. maxHealth — наибольшее здоровье, которое у неё может быть: позже зелье не сможет вылечить её выше этого значения.
Аннотируйте kira типом Hero, чтобы TypeScript проверил её по интерфейсу прямо там, где она создаётся. Без аннотации TypeScript вывел бы тип из объекта, и её heroClass был бы просто string: свойства объекта могут меняться, поэтому они получают более широкий тип, как вы видели с typeof в предыдущем уроке. Тогда describeHero(kira) стало бы ошибкой, ведь не всякая строка — это HeroClass.
Функция describeHero возвращает одну строку о герое, а основная программа её выводит. Соберите строку с помощью шаблонной строки, как в describeMonster. В конце урока вы выведете эту же строку ещё раз, уже после приключения Киры, так что функция здесь к месту.
Задание
- 1
Под
// Типынапишите типHeroClass: объединение литеральных типов"воин","маг"и"следопыт". - 2
Под ним напишите
interface Heroс именемnameтолько для чтения (строка), полемheroClassтипаHeroClassи числамиlevel,health,maxHealthиgold. - 3
Под
// Данныесоздайте константуkiraтипаHero: Кира, следопыт 3-го уровня, здоровье 34 из 50, золото 120. - 4
Под
// Функциинапишите функциюdescribeHero(hero: Hero): string, а под// Основная программавыведите то, что она возвращает для Киры:Кира, следопыт, уровень 3, здоровье 34/50, золото 120