Квесты
Теперь журнал квестов Киры. У каждого квеста есть название, и он активен, выполнен или провален. Квесты Киры мы уже добавили в данные под ней. У каждого статуса свои данные: награда reward есть только у выполненного квеста, а причина reason, по которой он провален, — только у проваленного. Это форма из урока «Моделирование данных», в которой невозможные сочетания записать нельзя: объединение с тегом, на этот раз называющимся status. Например, заказы в магазине:
type Order =
| { status: "waiting"; item: string }
| { status: "sent"; item: string; days: number }
| { status: "cancelled"; item: string; reason: string };
function describeOrder(order: Order): string {
switch (order.status) {
case "waiting":
return `${order.item}: заказ ждёт отправки`;
case "sent":
return `${order.item}: заказ отправлен, дней в пути: ${order.days}`;
case "cancelled":
return `${order.item}: заказ отменён, ${order.reason}`;
}
}
const orders: Order[] = [
{ status: "sent", item: "Верёвка", days: 2 },
{ status: "cancelled", item: "Фонарь", reason: "нет в наличии" },
];
for (const order of orders) {
console.log(describeOrder(order));
}Это выведет:
Верёвка: заказ отправлен, дней в пути: 2
Фонарь: заказ отменён, нет в наличииВ этом switch нет default с проверкой на never, и она ему не нужна: её работу делает тип возврата string. Если бы для какого-нибудь статуса не было case, функция могла бы закончиться, ничего не вернув, и TypeScript сообщил бы о её первой строке: Function lacks ending return statement and return type does not include 'undefined'. Оба способа встречаются часто: проверка полноты ещё и называет забытый тип, а один тип возврата короче.
У квестов в данных пока нет типа, поэтому TypeScript вывел его из объектов. Когда вы аннотируете массив типом Quest[], TypeScript проверит каждый квест по объединению. Например, о выполненном квесте без награды он сообщил бы:
main.ts(99,5): error TS2322: Type '{ status: "done"; title: string; }' is not assignable to type 'Quest'.
Property 'reward' is missing in type '{ status: "done"; title: string; }' but required in type '{ status: "done"; title: string; reward: number; }'.Задание
- 1
Под
Heroнапишите типQuest: объединение трёх объектных типов, у каждого из которых естьtitle(строка) иstatus. У активного квестаstatus: "open"; у выполненногоstatus: "done"иreward(число); а у проваленногоstatus: "failed"иreason(строка). Затем аннотируйте массивquestsтипомQuest[]. - 2
Под
findByNameнапишите функциюdescribeQuest(quest: Quest): stringсswitchпоquest.status. Для активного квеста она возвращает[активно] Потерянная корона, для выполненного —[выполнено] Волки в лесу: золото +50, а для проваленного —[провалено] Спасти мельника: мельница сгорела. - 3
В конце основной программы выведите
Квесты:, а затем каждый квест в циклеfor...of. Программа заканчивается так:Квесты: [выполнено] Волки в лесу: золото +50 [активно] Потерянная корона [провалено] Спасти мельника: мельница сгорела [выполнено] Мост гоблинов: золото +30