JavaRush /Курсы /Модуль 2: Fullstack /Интерфейсы для функций

Интерфейсы для функций

Модуль 2: Fullstack
5 уровень , 2 лекция
Открыта

3.1 Основы типизации сигнатур функций

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

Объявление интерфейса для функции

Для объявления интерфейса, описывающего сигнатуру функции, используется следующий синтаксис:

    
      interface FunctionName {
        (param1: type1, param2: type2, ...): returnType;
      }
    
  

Он определяет интерфейс с именем FunctionName, который описывает функцию с определенными параметрами и типом возвращаемого значения.

Пример:

JavaScript
    
      "use strict";
      let mySearch;
      mySearch = function (source, subString) {
        return source.indexOf(subString) > -1;
      };
      console.log(mySearch('Hello, world', 'world')); // Вывод: true
    
  
TypeScript
    
      interface SearchFunc {
        (source: string, subString: string): boolean;
      }

      let mySearch: SearchFunc;
      mySearch = function(source: string, subString: string): boolean {
        return source.indexOf(subString) > -1;
      };

      console.log(mySearch('Hello, world', 'world')); // Вывод: true
    
  

Здесь интерфейс SearchFunc описывает функцию, принимающую два параметра типа string и возвращающую значение типа boolean. Переменная mySearch соответствует этому интерфейсу.

3.2 Типизация параметров функции

Типизация параметров функции в интерфейсах позволяет строго контролировать типы аргументов, передаваемых в функцию.

Обязательные параметры

Все параметры функции в интерфейсах TypeScript по умолчанию обязательны, и передача неправильного количества или типа аргументов приведет к ошибке компиляции.

Пример:

JavaScript
    
      "use strict";
      let add;
      add = function (a, b) {
        return a + b;
      };
      console.log(add(5, 3)); // Вывод: 8
      console.log(add(5)); // Ошибка! TS: Expected 2 arguments, but got 1, JS: Nan, потому, что число + undefined = NaN
    
  
TypeScript
    
      interface AddFunc {
        (a: number, b: number): number;
      }

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

      console.log(add(5, 3)); // Вывод: 8
      console.log(add(5)); // Ошибка компиляции: Expected 2 arguments, but got 1.
    
  

Здесь интерфейс AddFunc описывает функцию, которая принимает два обязательных параметра типа number и возвращает значение типа number.

Опциональные параметры

TypeScript позволяет задавать опциональные параметры в функциях с помощью символа "?" после имени параметра.

Пример:

JavaScript
    
      "use strict";
      let concatenate;
      concatenate = function (str1, str2) {
        if (str2) {
          return str1 + str2;
        }
        else {
          return str1;
        }
      };
      console.log(concatenate('Hello')); // Вывод: Hello
      console.log(concatenate('Hello', ' World')); // Вывод: Hello World
    
  
TypeScript
    
      interface ConcatenateFunc {
        (str1: string, str2?: string): string;
      }

      let concatenate: ConcatenateFunc;
      concatenate = function(str1: string, str2?: string): string {
        if (str2) {
          return str1 + str2;
        } else {
          return str1;
        }
      };

      console.log(concatenate('Hello')); // Вывод: Hello
      console.log(concatenate('Hello', ' World')); // Вывод: Hello World
    
  

Здесь интерфейс ConcatenateFunc описывает функцию, где параметр str2 опциональный.

Параметры со значениями по умолчанию

Параметры функций могут иметь значения по умолчанию. Это позволяет вызывать функцию без явного указания значений для таких параметров.

Пример:

JavaScript
    
      "use strict";
      let greet;
      greet = function (name, greeting = 'Hello') {
        return `${greeting}, ${name}!`;
      };
      console.log(greet('Alice')); // Вывод: Hello, Alice!
      console.log(greet('Bob', 'Hi')); // Вывод: Hi, Bob!
    
  
TypeScript
    
      interface GreetFunc {
        (name: string, greeting?: string): string;
      }

      let greet: GreetFunc;
      greet = function(name: string, greeting: string = 'Hello'): string {
        return `${greeting}, ${name}!`;
      };

      console.log(greet('Alice')); // Вывод: Hello, Alice!
      console.log(greet('Bob', 'Hi')); // Вывод: Hi, Bob!
    
  

Здесь интерфейс GreetFunc описывает функцию, где параметр greeting имеет значение по умолчанию Hello.

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

Типизация возвращаемого значения функции в интерфейсах помогает контролировать тип результата, возвращаемого функцией.

Пример:

JavaScript
    
      "use strict";
      let multiply;
      multiply = function (a, b) {
        return a * b;
      };
      console.log(multiply(4, 5)); // Вывод: 20
    
  
TypeScript
    
      interface MultiplyFunc {
        (a: number, b: number): number;
      }

      let multiply: MultiplyFunc;
      multiply = function(a: number, b: number): number {
        return a * b;
      };

      console.log(multiply(4, 5)); // Вывод: 20
    
  

В этом примере интерфейс MultiplyFunc описывает функцию, которая принимает два параметра типа number и возвращает значение типа number.

Функции с неопределенным количеством параметров

TypeScript поддерживает функции с неопределенным количеством параметров с использованием остаточных параметров (rest parameters).

Пример:

JavaScript
    
      "use strict";
      let sum;
      sum = function (...numbers) {
          return numbers.reduce((acc, curr) => acc + curr, 0);
      };
      console.log(sum(1, 2, 3, 4)); // Вывод: 10
    
  
TypeScript
    
      interface SumFunc {
        (...numbers: number[]): number;
      }

      let sum: SumFunc;
      sum = function(...numbers: number[]): number {
        return numbers.reduce((acc, curr) => acc + curr, 0);
      };

      console.log(sum(1, 2, 3, 4)); // Вывод: 10
    
  

Здесь интерфейс SumFunc описывает функцию, которая принимает неопределенное количество параметров типа number и возвращает их сумму.

3.3 Примеры

Теперь рассмотрим примеры использования интерфейсов для функций в реальных проектах.

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

Пример 1: Обработчики событий

TypeScript
    
      interface EventHandler {
        (event: Event): void;
      }

      let clickHandler: EventHandler;
      clickHandler = function(event: Event): void {
        console.log(`Clicked: ${event.type}`);
      };

      document.addEventListener('click', clickHandler);
    
  

В этом примере интерфейс EventHandler описывает функцию-обработчик события, принимающую объект Event и возвращающую void.

Пример 2: Обработчики асинхронных операций

JavaScript
    
      "use strict";
      function fetchData(callback) {
          setTimeout(() => {
              let success = Math.random() <= 0.5;
              if (success) {
                  callback(null, { data: 'Sample data' });
              }
              else {
                  callback(new Error('Failed to fetch data'));
              }
          }, 1000);
      }
      fetchData((error, result) => {
        if (error) {
            console.error(`Error: ${error.message}`);
        }
        else {
            console.log(`Success: ${result.data}`); // Выведет: Success: Sample data
        }
      });
    
  
TypeScript
    
      interface AsyncCallback {
        (error: Error | null, result?: any): void;
      }

      function fetchData(callback: AsyncCallback): void {
        setTimeout(() => {
          let success = Math.random() <= 0.5;
          if (success) {
            callback(null, { data: 'Sample data' });
          } else {
            callback(new Error('Failed to fetch data'));
          }
        }, 1000);
      }

      fetchData((error, result) => {
        if (error) {
          console.error(`Error: ${error.message}`);
        } else {
          console.log(`Success: ${result.data}`); // Выведет: Success: Sample data
        }
      });
    
  

В этом примере интерфейс AsyncCallback описывает функцию обратного вызова для асинхронных операций, которая принимает параметры error и result.

Пример 3: Интерфейсы для функций высшего порядка

Функции высшего порядка принимают другие функции в качестве аргументов или возвращают их. Интерфейсы TypeScript позволяют описывать сигнатуры таких функций.

JavaScript
    
      "use strict";
      function applyTransform(input, transform) {
          return transform(input);
      }
      let toUpperCase = function (input) {
          return input.toUpperCase();
      };
      console.log(applyTransform('hello', toUpperCase)); // Вывод: HELLO
    
  
TypeScript
    
      interface TransformFunc {
        (input: string): string;
      }

      function applyTransform(input: string, transform: TransformFunc): string {
        return transform(input);
      }

      let toUpperCase: TransformFunc = function(input: string): string {
        return input.toUpperCase();
      };

      console.log(applyTransform('hello', toUpperCase)); // Вывод: HELLO
    
  
3
Задача
Модуль 2: Fullstack, 5 уровень, 2 лекция
Недоступна
Интерфейс для функции поиска
Интерфейс для функции поиска
3
Задача
Модуль 2: Fullstack, 5 уровень, 2 лекция
Недоступна
Функция сложения с интерфейсом
Функция сложения с интерфейсом
3
Задача
Модуль 2: Fullstack, 5 уровень, 2 лекция
Недоступна
Опциональные параметры в функции
Опциональные параметры в функции
3
Задача
Модуль 2: Fullstack, 5 уровень, 2 лекция
Недоступна
Функция с неопределенным количеством параметров
Функция с неопределенным количеством параметров
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ