Типизация параметров и возвращаемых значений

Урок: Типизация параметров и возвращаемых значений

Введение

В прошлом уроке мы научились работать с объектами и интерфейсами. До этого — типизировали переменные и параметры функций.

Но пока мы рассматривали это немного отдельно:

  • параметры функции — да, типизируем;
  • возвращаемое значение — иногда указываем, иногда нет.

Теперь важно соединить это в единую систему.

Представь функцию как «чёрный ящик»:

  • на вход приходят данные;
  • внутри происходит логика;
  • на выходе получается результат.

TypeScript позволяет строго описать:

  • что входит в функцию;
  • что выходит из неё.

Главная идея урока: функция должна быть полностью предсказуемой — и по входным данным, и по результату.


Типизация параметров — повторение с усилением

Мы уже видели базовый пример:

function add(a: number, b: number): number {
  return a + b;
}

console.log('числа:', add(2, 3));
// add('2', '3'); // ошибка TS: ожидаются number

Здесь:

  • параметры a: number, b: number;
  • без типов в JavaScript те же значения дали бы конкатенацию строк.

Но теперь важно понять:

тип параметров — это не просто проверка, это контракт функции.

Ты как будто говоришь:

"Я принимаю только числа. Всё остальное — ошибка."


Типизация возвращаемого значения

Теперь добавим вторую часть — результат.

function add(a: number, b: number): number {
  return a + b;
}
console.log('сумма 2 и 3:', add(2, 3));

Что изменилось:

  • : number после скобок — это тип возвращаемого значения;
  • теперь TypeScript проверяет не только вход, но и выход.

Почему важно указывать возвращаемый тип

На первый взгляд может показаться, что это лишнее — ведь TypeScript умеет сам определять тип.

Но давай посмотрим на пример.

function getUserName(_id: number): string {
  return 'Alex';
}

Теперь если кто-то изменит функцию:

function getUserName(id) {
  return 123;
}

console.log('результат:', getUserName(1));

Ошибка проявится позже — когда ты начнёшь использовать результат. В TypeScript с аннотацией : string такой return 123 не прошёл бы компиляцию.


Как это влияет на использование функции

function getUserName(_id: number): string {
  return 'Alex';
}
const name = getUserName(1);
console.log('строка в верхнем регистре:', name.toUpperCase());

TypeScript знает:

  • name — это строка;
  • значит, можно использовать строковые методы.

Если бы тип был неопределён или any, такой уверенности не было бы.


Использование интерфейсов в параметрах

Теперь соединим это с предыдущим уроком.

interface User {
  name: string;
  age: number;
}

function printUser(user: User): string {
  return `${user.name} is ${user.age}`;
}

console.log(printUser({ name: 'Alex', age: 30 }));
// console.log(printUser({ name: 'Alex' })); // ошибка TS: нет age

TypeScript контролирует всё: и вход, и выход.


Функции, которые ничего не возвращают

Иногда функция не возвращает значение.

function logMessage(message: string): void {
  console.log(message);
}

const result = logMessage('Hello');
console.log('result после void-функции:', result);

Частые ошибки и как их избежать

1. Не указывать возвращаемый тип

function multiply(a: number, b: number): number {
  return a * b;
}
console.log('произведение:', multiply(3, 4));

Работает, но:

  • в больших проектах лучше указывать явно;
  • это делает код стабильнее.

2. Использовать any

function process(data: any): any {
  return data;
}
console.log('данные проходят «как есть»:', process({ id: 1 }));

Это ломает всю идею TypeScript:

  • нет проверки;
  • нет подсказок;
  • больше ошибок.

3. Несоответствие типов

function isAdult(_age: number): boolean {
  return true;
}
console.log('ожидали true/false:', isAdult(20));
// Неверный пример для контракта:
// function isAdultBad(_age: number): boolean {
//   return 'yes'; // ошибка TS: string не boolean
// }

TypeScript не позволит вернуть неправильный тип, если возвращаемый тип указан явно.


Как это используется в реальных задачах

Рассмотрим пример логики авторизации:

interface LoginData {
  username: string;
  password: string;
}

function login(data: LoginData): boolean {
  if (data.username === 'admin' && data.password === '1234') {
    return true;
  }
  return false;
}
console.log('успешный вход:', login({ username: 'admin', password: '1234' }));
console.log('неверный пароль:', login({ username: 'admin', password: '0000' }));

Что здесь важно:

  • вход строго описан;
  • выход предсказуем (boolean);
  • функцию сложно использовать неправильно.

Связь с Playwright (подготовка к следующему уроку)

В тестировании это особенно важно.

Например:

  • функция возвращает Locator;
  • функция принимает Page;
  • методы возвращают Promise.

Если типы не заданы:

  • легко ошибиться;
  • сложно понять, что происходит.

В следующем уроке мы как раз применим всё это в Playwright.


Итоговое понимание

Функция — это не просто кусок кода, а чётко описанный механизм:

  • что она принимает;
  • что она возвращает;
  • как с ней работать.

Типизация параметров и возвращаемых значений делает этот механизм прозрачным и надёжным.

Главная мысль урока:

TypeScript превращает функции в предсказуемые контракты, где невозможно случайно передать неправильные данные или получить неожиданный результат.

И именно это даёт уверенность в коде — особенно когда он становится сложнее и начинает взаимодействовать с реальными инструментами, такими как Playwright.