📘 TypeScript

Functions and Recursion in TypeScript 5 (Node.js): Complete Guide for Beginners

Функции и рекурсия в TypeScript

Введение: зачем нужны функции?

Представь, что ты пишешь программу, которая несколько раз считает площадь круга. Каждый раз нужно писать 3.14 * радиус * радиус. Это скучно и легко ошибиться! Функции — это как маленькие «роботы», которые выполняют одно и то же действие по команде. Ты даёшь им данные (аргументы), они делают работу и возвращают результат.

В TypeScript (который работает на Node.js) функции помогают:

  • Не повторять один и тот же код
  • Делать программу понятной
  • Легко исправлять ошибки (изменил в одном месте — всё работает)

Синтаксис функций в TypeScript

В TypeScript 5 мы указываем типы данных для аргументов и результата. Это как подписать коробки: «сюда кладём только числа», «отсюда берём строку».

// Простая функция: складывает два числа
function sum(a: number, b: number): number {
  return a + b;
}

// Вызов функции
console.log(sum(5, 3)); // 8

Разберём по частям:

  • function — ключевое слово «создать функцию»
  • sum — имя (придумываешь сам)
  • (a: number, b: number) — аргументы с типами
  • : number — тип результата (что вернём)
  • { return a + b; } — тело функции, return отдаёт результат

Функции с разными типами

Можно возвращать строки, булевы значения, даже ничего (void):

// Функция, которая ничего не возвращает (просто печатает)
function greet(name: string): void {
  console.log(`Привет, ${name}!`);
}

// Функция, проверяющая чётность числа
function isEven(num: number): boolean {
  return num % 2 === 0;
}

greet("Аня"); // Привет, Аня!
console.log(isEven(4)); // true

Стрелочные функции (современный стиль)

В TypeScript 5 часто используют короткую запись через =>:

const multiply = (x: number, y: number): number => x * y;

console.log(multiply(4, 5)); // 20

Если действий несколько — нужны фигурные скобки и return:

const describeNumber = (n: number): string => {
  if (n > 0) return "Положительное";
  if (n < 0) return "Отрицательное";
  return "Ноль";
};

Рекурсия — функция вызывает саму себя

Рекурсия — это когда функция внутри себя вызывает... себя же! Как матрёшка: большая кукла открывается, внутри ещё одна, и так до самой маленькой.

Важное правило: у рекурсии должен быть базовый случай (когда остановиться), иначе программа зависнет.

Пример: факториал числа

Факториал числа 5 (обозначается 5!) — это 5 × 4 × 3 × 2 × 1 = 120.

function factorial(n: number): number {
  // Базовый случай: факториал 0 или 1 равен 1
  if (n <= 1) return 1;
  
  // Рекурсивный случай: n! = n * (n-1)!
  return n * factorial(n - 1);
}

console.log(factorial(5)); // 120

Как это работает шаг за шагом:

  • factorial(5) → 5 * factorial(4)
  • factorial(4) → 4 * factorial(3)
  • factorial(3) → 3 * factorial(2)
  • factorial(2) → 2 * factorial(1)
  • factorial(1) → 1 (базовый случай!)
  • Теперь всё собирается обратно: 2*1=2, 3*2=6, 4*6=24, 5*24=120

Типичные задачи с рекурсией

Задача 1: Числа Фибоначчи

Каждое число равно сумме двух предыдущих: 0, 1, 1, 2, 3, 5, 8, 13...

function fibonacci(n: number): number {
  if (n <= 0) return 0;
  if (n === 1) return 1;
  return fibonacci(n - 1) + fibonacci(n - 2);
}

// Выведем первые 10 чисел
for (let i = 0; i < 10; i++) {
  console.log(`fib(${i}) = ${fibonacci(i)}`);
}

Задача 2: Сумма цифр числа

function sumDigits(num: number): number {
  // Берём последнюю цифру и отбрасываем её
  if (num < 10) return num;
  return (num % 10) + sumDigits(Math.floor(num / 10));
}

console.log(sumDigits(1234)); // 1+2+3+4 = 10

Задача 3: Возведение в степень

function power(base: number, exp: number): number {
  if (exp === 0) return 1;
  return base * power(base, exp - 1);
}

console.log(power(2, 5)); // 32

Работа с вводом/выводом (stdin/stdout)

В Node.js для чтения с клавиатуры используем readline. Вот пример программы, которая спрашивает число и выводит его факториал:

import * as readline from 'readline';

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

function factorial(n: number): number {
  if (n <= 1) return 1;
  return n * factorial(n - 1);
}

rl.question('Введите число: ', (answer: string) => {
  const num = parseInt(answer);
  if (isNaN(num) || num < 0) {
    console.log('Пожалуйста, введите неотрицательное целое число');
  } else {
    console.log(`Факториал ${num} = ${factorial(num)}`);
  }
  rl.close();
});

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

Ошибка 1: Забыли базовый случай

// НЕПРАВИЛЬНО — будет бесконечная рекурсия!
function badFactorial(n: number): number {
  return n * badFactorial(n - 1); // Нет условия остановки
}

// ПРАВИЛЬНО
function goodFactorial(n: number): number {
  if (n <= 1) return 1; // Базовый случай
  return n * goodFactorial(n - 1);
}

Ошибка 2: Неправильный тип аргумента