Типизация функций: параметры и возврат
Типизация функций в TypeScript — явное указание типов параметров и возвращаемого значения, что позволяет компилятору проверять корректность вызовов и гарантировать контракт функции.
Зачем нужно
Параметры функций — единственное место, где TypeScript не может вывести типы из контекста: без аннотаций они получат тип any (или ошибку при noImplicitAny). Явный возвращаемый тип документирует контракт и защищает от случайного изменения при рефакторинге.
Где используется
- Все функции, принимающие данные снаружи (API, пользовательский ввод)
- Публичное API модуля или класса
- Callback-параметры и функции высшего порядка
- Async-функции с явным типом промиса
Основной контент
Основной синтаксис
// Обычная функция
function add(a: number, b: number): number {
return a + b;
}
// Стрелочная функция
const multiply = (a: number, b: number): number => a * b;
// Возвращаемый тип можно опустить — TypeScript выведет
const double = (n: number) => n * 2; // (n: number) => number
Опциональные и default параметры
function greet(name: string, title?: string): string {
return title ? `${title} ${name}` : name;
}
function log(message: string, level: "info" | "warn" | "error" = "info"): void {
console[level](message);
}
Rest параметры
function sum(...numbers: number): number {
return numbers.reduce((acc, n) => acc + n, 0);
}
function join(separator: string, ...parts: string): string {
return parts.join(separator);
}
sum(1, 2, 3, 4); // 10
join("-", "a", "b", "c"); // "a-b-c"
Void и never
// void — функция ничего не возвращает
function log(msg: string): void {
console.log(msg);
}
// never — функция никогда не завершится нормально
function fail(message: string): never {
throw new Error(message);
}
function infiniteLoop: never {
while (true) {}
}
Перегрузки (overloads)
// Объявления перегрузок
function format(value: string): string;
function format(value: number, decimals?: number): string;
// Реализация (должна покрывать все варианты)
function format(value: string | number, decimals = 2): string {
if (typeof value === "string") return value.toUpperCase();
return value.toFixed(decimals);
}
format("hello"); // string — первая перегрузка
format(3.14159, 2); // string — вторая перегрузка
Функциональные типы
// type alias для типа функции
type Predicate<T> = (value: T) => boolean;
type Transform<A, B> = (input: A) => B;
type Comparator<T> = (a: T, b: T) => number;
// Параметр-функция
function filter<T>(arr: T, predicate: Predicate<T>): T {
return arr.filter(predicate);
}
const isPositive: Predicate<number> = (n) => n > 0;
filter([1, -2, 3, -4], isPositive); // [1, 3]
Async функции
// Явный тип возврата для async — Promise<T>
async function fetchUser(id: string): Promise<User> {
const res = await fetch(`/api/users/${id}`);
return res.json();
}
// Promise<void> — async без возврата значения
async function sendEmail(to: string, body: string): Promise<void> {
await mailer.send({ to, body });
}
// Promise<User | null>
async function findUser(id: string): Promise<User | null> {
const user = await db.users.findById(id);
return user ?? null;
}
this parameter
interface Timer {
seconds: number;
start(this: Timer): void;
}
const timer: Timer = {
seconds: 0,
start(this: Timer) {
setInterval(() => {
this.seconds++; // this: Timer
}, 1000);
},
};
Частые ошибки
- Не аннотировать параметры — с
noImplicitAny: trueэто ошибка; без него — скрытыйany. - Возвращать разные типы без явного union —
return x > 0 ? "ok" : 42выведетstring | number; лучше явно указать. - Путать
voidиundefined— функция сvoidможет вернутьundefined, ноvoidиundefinedне взаимозаменяемы как типы. - Перегрузки без реализации, покрывающей все случаи — реализация должна принимать union всех вариантов параметров.
Связанные темы
- Типы для callback функций
- Optional и Default параметры
- Generic функции
- Типы -- null, undefined, void, never
- _MOC TypeScript