Функции
Функции
Технический фундамент типового контракта функции
У функции в TS есть две критичные части контракта:
- тип входов (параметры, их обязательность, порядок);
- тип выхода (что вызывающий код гарантированно получит).
Дополнительно важно помнить:
- перегрузки описывают внешний API, но реализация должна покрывать все сигнатуры;
- union-параметры требуют narrowing перед специфичными операциями;
- слишком широкий тип функции быстро "размывает" типовую безопасность по цепочке вызовов.
Почему типизация функций критична
Функции связывают модули между собой. Если у функции неясный контракт, ошибка легко распространяется по всему проекту: передали не тот аргумент, получили неожиданный тип результата, сломали бизнес-логику. TypeScript позволяет явно описать вход и выход функции.
Ключевой момент: функция в TypeScript это контракт параметров + контракт возвращаемого значения.
Проверь себя: почему тип возвращаемого значения так же важен, как тип входных параметров?
Базовая аннотация функции
function sum(a: number, b: number): number {
return a + b;
}
Здесь:
a: number,b: number- типы параметров;: numberпосле скобок - тип результата.
Смотри, что важно: TypeScript часто выводит возвращаемый тип сам, но явная аннотация полезна для публичного API.
Опциональные и дефолтные параметры
function greet(name: string, title?: string): string {
return title ? `${title} ${name}` : name;
}
function createUser(name: string, role: string = 'user'): string {
return `${name}:${role}`;
}
?делает параметр необязательным;=задает значение по умолчанию.
Здесь часто путаются: обязательные параметры должны идти раньше опциональных.
Rest-параметры
Когда аргументов может быть много, используют rest.
function total(...values: number[]): number {
return values.reduce((acc, x) => acc + x, 0);
}
Новый термин: rest-параметр - сбор множества аргументов в массив.
Проверь себя: чем ...values: number[] отличается от параметра values: number[]?
Тип функции через alias
Для переиспользования сигнатуры удобно делать alias.
type Comparator = (a: number, b: number) => number;
const asc: Comparator = (a, b) => a - b;
Это особенно полезно в колбэках и сервисах с одинаковым типом функций.
Перегрузки (overloads)
Когда функция поддерживает несколько форм входа, можно описать перегрузки.
function format(value: number): string;
function format(value: string): string;
function format(value: number | string): string {
return String(value).trim();
}
Смотри, что важно: сигнатуры перегрузки описывают внешний контракт, а реализация использует объединенный тип.
Реальные микро-сценарии
- API-утилита
request.
Типы параметров и результата снижают риск неправильного вызова.
- Форматтеры дат и цен.
Явные типы гарантируют, что функция не получит неподходящий формат.
- Callback-и сортировки.
Сигнатура компаратора защищает от некорректного результата сравнения.
Частые ошибки новичков
- Забывать тип возвращаемого значения в ключевых функциях.
- Использовать
anyв параметрах вместо конкретного или union-типа. - Переусложнять перегрузки без реальной необходимости.
- Смешивать
undefined-ветки без явного контракта.
Анти-провал: если функция часто используется в проекте, обязательно зафиксируй ее сигнатуру максимально точно.
Что будет, если изменить входные данные
Если sum получает '2' вместо 2, TypeScript даст ошибку на этапе компиляции. В JS это могло бы привести к строковой конкатенации или NaN в сложной формуле. Явный контракт функции защищает от таких тихих сбоев.
Проверь себя: в каком случае лучше number | string, а в каком лучше оставить строго number и нормализовать вход заранее?
Краткий итог
- Типизация функций фиксирует входы и выходы, делая API предсказуемым.
- Опциональные, дефолтные и rest-параметры помогают описывать реальные сценарии вызова.
- Alias и перегрузки делают код выразительным при сложных интерфейсах.
- Четкие сигнатуры сильно упрощают поддержку и рефакторинг.
- Большая часть багов интеграции уходит, когда функции имеют строгий типовой контракт.