Необязательные параметры
Иногда аргумент действительно можно не передавать. Трактирщик приветствует каждого гостя, но титул, например сэр или леди, есть не у всех. TypeScript сообщил бы о вызове без титула (Expected 2 arguments, but got 1.), поэтому нужно сказать, что параметр необязателен: поставьте вопросительный знак после его имени:
function greet(name: string, title?: string): string {
if (title === undefined) {
return `Добро пожаловать, ${name}!`;
}
return `Добро пожаловать, ${title} ${name}!`;
}
console.log(greet("Кира"));
console.log(greet("Бруно", "сэр"));Это выведет:
Добро пожаловать, Кира!
Добро пожаловать, сэр Бруно!Теперь greet принимает один или два аргумента. Если передать три, TypeScript сообщит Expected 1-2 arguments, but got 3.
Когда аргумент не передан, параметр равен undefined, как и в JavaScript. Поэтому внутри функции title — это не просто string. Его тип — string | undefined: «строка или undefined». (Знак | означает «или». Таким типам посвящён урок об объединениях и сужении типов.) TypeScript не позволит использовать title как строку, пока вы не проверите, что он не undefined:
function greet(name: string, title?: string): string {
return `Добро пожаловать, ${title.toUpperCase()} ${name}!`;
}
console.log(greet("Кира"));main.ts(2,33): error TS18048: 'title' is possibly 'undefined'.'title' is possibly 'undefined' («title, возможно, равен undefined»): в JavaScript greet("Кира") упал бы здесь с ошибкой TypeError: Cannot read properties of undefined (reading 'toUpperCase'). TypeScript сообщает о ней до запуска программы.
В первом примере if обрабатывает гостя без титула и возвращает результат. TypeScript следит за условиями в вашем коде, поэтому знает, что ниже этого if параметр title может быть только string, и позволяет использовать его как строку.
Но будьте осторожны с шаблонными строками. TypeScript пропускает в них undefined, и он превращается в текст undefined. Без проверки greet("Кира") вернул бы Добро пожаловать, undefined Кира! без всякой ошибки. Здесь проверка остаётся за вами.
Необязательные параметры идут после обязательных. Аргументы попадают в параметры по порядку, так что иначе greet("Кира") положил бы "Кира" в титул:
function greet(title?: string, name: string): string {
return `Добро пожаловать, ${name}!`;
}main.ts(1,32): error TS1016: A required parameter cannot follow an optional parameter.Типичные ошибки:
- Параметр используется без проверки:
'title' is possibly 'undefined'. - Вопросительный знак после типа,
title: string?, а не после имени. TypeScript сообщает'?' at the end of a type is not valid TypeScript syntax. Did you mean to write 'string | undefined'?Вопросительный знак ставится сразу после имени параметра:title?: string.
Задание
- 1
У второго задания нет бонуса. Сделайте параметр
bonusнеобязательным. TypeScript тогда сообщит'bonus' is possibly 'undefined'.Исправьте это: когдаbonusравенundefined, функция возвращает простоreward. Программа выведет70и30. - 2
Напишите функцию
rewardTextс параметромtitleтипаstring, необязательным параметромgoldтипаnumberи возвращаемым типомstring. Если золото передано, она возвращает строку видаВолки в лесу: 70 золота, а если нет —Потерянная корона: без награды. ВыведитеrewardText("Волки в лесу", totalReward(50, 20))иrewardText("Потерянная корона"). Программа выведет:70 30 Волки в лесу: 70 золота Потерянная корона: без награды