Опциональные параметры, значения по умолчанию и rest

Делаем функции гибкими: необязательные аргументы, значения по умолчанию и переменное число параметров.

Знак ? после имени параметра делает его опциональным — его можно не передавать.

Опциональные параметры

Не все аргументы обязательны. Опциональный параметр помечают ?. Внутри функции его тип автоматически становится тип | undefined — то есть его может не быть:

function greet(name: string, greeting?: string): string {
  if (greeting === undefined) {
    return "Привет, " + name;
  }
  return greeting + ", " + name;
}

greet("Аня");            // "Привет, Аня"
greet("Аня", "Здравствуй"); // "Здравствуй, Аня"

Компилятор требует обработать случай, когда параметр не передан — иначе можно обратиться к undefined. Опциональные параметры всегда идут после обязательных.

Значения по умолчанию

Часто вместо проверки на undefined удобнее задать значение по умолчанию. Тогда параметр не обязателен, но всегда имеет осмысленное значение:

function greet(name: string, greeting: string = "Привет"): string {
  return greeting + ", " + name;
}

greet("Боря");            // "Привет, Боря"
greet("Боря", "Салют");   // "Салют, Боря"

Тип greeting здесь выводится из значения по умолчанию как string — аннотацию можно даже опустить. Внутри функции это уже точно строка, без undefined, поэтому проверка не нужна.

? или значение по умолчанию?

ПодходКогда применять
param?: Tотсутствие параметра несёт особый смысл, обрабатываете вручную
param: T = значениеесть разумное значение по умолчанию

Rest-параметры

Когда число аргументов заранее неизвестно, используют rest-параметр .... Он собирает все «лишние» аргументы в массив:

function sum(...numbers: number[]): number {
  return numbers.reduce((acc, n) => acc + n, 0);
}

sum(1, 2);          // 3
sum(1, 2, 3, 4, 5); // 15
sum();              // 0

Тип number[] гарантирует, что все переданные аргументы — числа. Передать строку нельзя:

sum(1, "2"); // Ошибка: Argument of type 'string' is not assignable to parameter of type 'number'.

Рабочий пример

function joinPath(...parts) {
  return parts.join("/");
}

console.log(joinPath("usr", "local", "bin"));
console.log(joinPath("home", "anya"));

Вывод:

usr/local/bin
home/anya

Rest-параметр всегда стоит последним в списке — после него других параметров быть не может.

Итог

  • param?: T делает параметр необязательным; внутри его тип — T | undefined.
  • Значение по умолчанию param: T = ... избавляет от проверки на undefined.
  • Rest-параметр ...args: T[] собирает произвольное число типизированных аргументов в массив и стоит последним.
Проверьте себя
1. Какой тип имеет опциональный параметр greeting?: string внутри функции?
Astring
Bstring | undefined
Cany
Dvoid
2. Чем значение по умолчанию удобнее опционального параметра с ?
AОно ускоряет функцию
BПараметр всегда имеет значение, поэтому проверка на undefined не нужна
CОно позволяет передавать любой тип
DОно делает параметр обязательным
3. Что собирает rest-параметр ...numbers: number[]?
AТолько первый переданный аргумент
BВсе переданные аргументы в массив чисел
CОбъект с аргументами
DСтроку из аргументов
Поддержать проект