ПрограммированиеTypescript-разработчик

Как работает типизация функций с перегрузкой (overload) в TypeScript, и в чем её отличие от перегрузки методов в других языках?

Проходите собеседования с ИИ помощником Hintsage

Ответ.

История вопроса

В языках наподобие Java или C# перегрузка функций и методов — стандартная возможность: можно объявить несколько функций с одним именем, но разными параметрами. В JavaScript этого нет, что добавляет потенциальные ошибки. TypeScript решает эту задачу на уровне типов.

Проблема

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

Решение

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

Пример кода:

function sum(a: number, b: number): number; function sum(a: string, b: string): string; function sum(a: any, b: any): any { return a + b; } const a = sum(1, 2); // 3 const b = sum('foo', 'bar'); // "foobar"

Ключевые особенности:

  • Всегда одна реализация после всех сигнатур
  • Реализация должна быть совместима со всеми вариантами перегрузки
  • TypeScript проверяет правильность вызова при использовании перегруженной функции

Вопросы с подвохом.

Можно ли определить реализацию функции до объявления всех сигнатур перегрузки?

Нет, сначала должны быть все сигнатуры перегрузки, а потом реализация. Ошибка:

// Ошибка! Сначала сигнатуры, потом реализация function foo(a: number): number { return a } // ошибка function foo(a: string): string { return a } // ошибка

TypeScript проверяет возвращаемые значения во всех сигнатурах перегрузки?

TypeScript гарантирует возврат типов согласно объявленным сигнатурам только на этапе компиляции; никакой проверки типов во время выполнения не происходит.

Обязательно ли покрывать все варианты входных данных в единственной реализации?

Функция-реализация должна корректно обрабатывать все варианты входных данных согласно сигнатурам перегрузки:

function parse(a: number): string; function parse(a: string): string; function parse(a: number | string): string { return String(a); }

Типовые ошибки и анти-паттерны

  • Несовпадение реализации и сигнатуры перегрузок
  • Неправильный порядок объявления сигнатур и реализации
  • Неявная обработка/игнорирование комбинаций типов

Пример из жизни

Негативный кейс

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

Плюсы:

  • Гибкое API для пользователей функции

Минусы:

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

Позитивный кейс

Каждая перегрузка функции покрывается условием на типы внутри реализации, используются проверки типа (typeof/instanceof).

Плюсы:

  • API безопасно и предсказуемо
  • Ошибки ловятся на этапе компиляции

Минусы:

  • Увеличивает кодовую базу за счет дополнительных проверок