- Указывать типы параметров и возвращаемого значения
- Использовать необязательные параметры, параметры по умолчанию и rest-параметры
- Записывать типы функций вроде
(a: number) => numberи понимать контекстную типизацию - Знать, что означают типы
voidиnever
Функция — это своего рода договор: что она принимает и что возвращает. В JavaScript этот договор живёт лишь в памяти программиста или в комментариях, а комментарии быстро устаревают. В TypeScript договор записан прямо в заголовке функции, и компилятор проверяет, что он соблюдается при каждом вызове, — и когда ты пишешь функцию, и когда её используешь.
Параметры и возвращаемое значение
Тип каждого параметра пишут после его имени через двоеточие. Тип возвращаемого значения ставят после скобок. Функция ниже считает чаевые в ресторане:
function calculateTip(bill: number, percent: number): number {
return (bill * percent) / 100;
}
const tip = calculateTip(40, 15);
console.log(`Tip: ${tip} AZN`);Tip: 6 AZN
Компилятор проверяет обе стороны договора. Вызывающий код должен передать все аргументы нужных типов, а тело функции — вернуть обещанный тип:
function calculateTip(bill: number, percent: number): number {
return (bill * percent) / 100;
}
calculateTip(40);
function isAdult(age: number): boolean {
if (age >= 18) {
return 'yes';
}
return false;
}tip.ts:5:1 - error TS2554: Expected 2 arguments, but got 1.
5 calculateTip(40);
~~~~~~~~~~~~
tip.ts:1:37
1 function calculateTip(bill: number, percent: number): number {
~~~~~~~~~~~~~~~
An argument for 'percent' was not provided.
tip.ts:9:5 - error TS2322: Type 'string' is not assignable to type 'boolean'.
9 return 'yes';
~~~~~~Необязательные параметры, значения по умолчанию и rest
- Необязательный параметр отмечают
?после имени:greeting?: string. На самом деле его тип —string | undefined, то есть его можно не передавать. - Параметр со значением по умолчанию (
currency = 'AZN') получает тип из этого значения — здесьstring. Если аргумент не передан, используется значение по умолчанию. - Rest-параметр (
...numbers: number[]) собирает любое количество аргументов в массив. - Необязательные параметры должны идти после обязательных.
function greet(name: string, greeting?: string): string {
return `${greeting ?? 'Hello'}, ${name}!`;
}
function price(amount: number, currency = 'AZN'): string {
return `${amount.toFixed(2)} ${currency}`;
}
function sum(...numbers: number[]): number {
return numbers.reduce((total, n) => total + n, 0);
}
console.log(greet('Murad'));
console.log(greet('Murad', 'Salam'));
console.log(price(12.5), '|', price(12.5, 'USD'));
console.log(sum(1, 2, 3), sum());Hello, Murad! Salam, Murad! 12.50 AZN | 12.50 USD 6 0
?? подставляет 'Hello', если greeting не передан.Поскольку необязательный параметр может быть undefined, TypeScript не даёт использовать его без проверки. В greet мы подставили запасное значение через ??; если забыть об этом, получится вот что:
function shout(name: string, greeting?: string): string {
return `${greeting.toUpperCase()}, ${name}!`;
}shout.ts:2:13 - error TS18048: 'greeting' is possibly 'undefined'.
2 return `${greeting.toUpperCase()}, ${name}!`;
~~~~~~~~Типы функций
В JavaScript функции — обычные значения: их можно сохранять в переменные и передавать в другие функции как аргументы. Значит, у функции тоже есть тип. Тип функции записывают стрелочным синтаксисом: (a: number, b: number) => number — «функция, которая принимает два числа и возвращает число». Такому типу удобно дать имя через type.
type Operation = (a: number, b: number) => number;
const add: Operation = (a, b) => a + b;
const multiply: Operation = (a, b) => a * b;
function calculate(x: number, y: number, op: Operation): number {
return op(x, y);
}
console.log(calculate(6, 7, add));
console.log(calculate(6, 7, multiply));
console.log([1, 2, 3].map((n) => n * 10));13 42 [ 10, 20, 30 ]
Обрати внимание: в add мы не указали типы a и b, но ошибки нет. Это контекстная типизация (contextual typing): функция записана в переменную типа Operation, поэтому TypeScript знает, что параметры — number. С map то же самое: массив состоит из чисел, поэтому n автоматически получает тип number.
| Тип | Значение | Пример |
|---|---|---|
void | функция не возвращает ничего полезного | function log(msg: string): void |
never | функция никогда не завершается нормально — например, всегда бросает ошибку | function fail(msg: string): never |
| тип функции | параметры и возвращаемый тип | (a: number, b: number) => number |
Главное
- Типы параметров пишут после их имён, а возвращаемый тип — после скобок.
- Компилятор проверяет количество и типы аргументов, а в теле функции — возвращаемое значение.
x?: T— необязательный параметр типаT | undefined;x = значение— значение по умолчанию;...xs: T[]— rest-параметр.- Тип функции записывают со стрелкой:
(a: number, b: number) => number; контекстная типизация сама определяет типы параметров. void— ничего не возвращает,never— никогда не завершается нормально.
Проверь себя
Вопросов: 10. Каждый правильный ответ приносит XP.
(a: number, b: number) => number?