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

Как реализовать перегрузку функций (function overloading) в TypeScript и чем перегрузка отличается от перегрузки в других языках, например, C# или Java?

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

Ответ

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

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

Пример:

function greet(person: string): string; function greet(person: string, age: number): string; function greet(person: string, age?: number): string { if (age !== undefined) { return `Hello, ${person}. You are ${age}!`; } else { return `Hello, ${person}!`; } } greet('Alice'); // 'Hello, Alice!' greet('Bob', 32); // 'Hello, Bob. You are 32!'

⚠️ В отличие от C# или Java, нет нескольких реализаций функции — все сигнатуры разрешаются в одну функцию с обязательной проверкой внутри.

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

Нужно ли реализовывать каждую перегруженную сигнатуру в TypeScript в виде отдельной функции, как, например, в C#?

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

Примеры реальных ошибок из-за незнания тонкостей темы


История

На проекте разработчик объявил две функции с одинаковым названием, рассчитывая на перегрузку, как в Java. В итоге работала только последняя определенная функция, а остальные были "затёрты". Это привело к неожиданным ошибкам в работе и огромным временным затратам на рефакторинг.


История

Не реализовали корректную проверку типов внутри реализации перегруженной функции. Функция периодически возвращала значения не того типа, что ожидали клиенты, что стало причиной сложности отлова ошибки из-за того, что TypeScript не валидирует реализацию перегрузок.


История

Использовали реализацию перегрузки только на уровне типов (объявили сигнатуры), но не обеспечили совместимость с runtime-реализацией (отсутствие опциональных параметров и обработок внутри функции). Это привело к падениям при вызове с "валидными по типу" параметрами, потому что runtime этих вариантов не поддерживал.