Comments 18
А почему вы думаете, что "не найдут" информацию о перегрузке те, кто пришёл из мира js? У них такого хватает – к примеру, chrome.tabs.query. И при переходе на ts всё это надо как-то типизировать.
Скорей проблемы возникнут у плюсовиков: перегрузки функций ведь по факту нет, есть перегрузка только типов функций.
Ну и понять такую перегрузку (если можешь в типы данных) достаточно просто, достаточно вспомнить про алгебраические типы. Т.е. тип функции (не результата, а самой функции) – это просто тип или из первой декларации, или из второй. Можно этот тип выписать отдельно, через "|". Соответственно, и использовать при желании можно примерно везде...
Перегрузки в TS не через union, а через intersection создаются из-за номинальной типизации:
type ICallString = {
(arg0: string): string
}
type ICallNumber = {
(arg0: number): number
}
type F = ICallString & ICallNumber;
Гуглить по ковариантность и контрвариантность типов в TS
А почему вы думаете, что "не найдут" информацию о перегрузке те, кто пришёл из мира js?
Я узнал о перегрузках только через три года работы. Все как в статье, если ты копаешься только в своих проектах, то перегрузки ты скорее всего нигде не встретишь)
А я использовал перегрузку в своём первом пет-проекте. Функция меняла страницу. Булевое значение - след/пред страница, или число - номер страницы. Потом я понял, что так делать нехорошо, но до сих пор не исправил? (возможность передать номер я добавил по приколу и нигде не использовал, только булевые, хихи)
Перегрузка - прекрасный инструмент. В языках, где перегрузка делается манглированием, ситуация получше, там функций несколько с одинаковым именем, то есть несколько реализаций. Это позволяет не выдумывать разные имена при отличии аргументов, что нужно довольно часто. Например метод суммирования логично назвать Sum, а не SumInt, SumFloat, SumDouble, SumShort, SumLong, SumUint, SumUlong, ... А потом DivideInt, DivideFloat, DivideDouble, ... и всё прочее по списку.
А когда вот так нужно сначала написать сигнатуры методов и потом слепить реализацию в одну на ифах - это какая-то жесть. Тут нет ни выигрыша в понятности кода (сначала сигнатуры потом огород ифов и борьба с аргументами), ни выигрыша в производительности (компиляция большой функции и разбор аргументов ифами, вместо исполнения только нужной отдельной функции), ни простого добавления очередной функции (придётся переписать реализацию). Всё это есть при "нормальной" перегрузке.
Ещё пример где перегрузка нужна - это конструктор. Например когда какой-то метод создаёт объект, зная только его класс. Такой метод не знает с какими аргументами создать этот объект, поэтому создаёт его дефолтным образом - без аргументов, просто new Object()
или CreateInstance( type )
. А если требуется создавать такой объект "вручную", то для этого пишется перегрузка с нужными аргументами.
Для JS и отчасти TS это менее полезно потому, что в них функция принимает на вход что угодно и так. А в статически типизированных языках функция не может принимать что угодно на вход, ей нужно скомпилироваться во что-то конкретное.
Полностью согласен. В java перегрузка прекрасна, но в ts она выглядит слишком монструозно и несуразно, что как будто бы весь смысл использования высосан из пальца и проще просто использовать разные имена
Может, я чего-то не понял, но дженерик для вашего случая выглядит гораздо более подходящим решением. Особенно если в вашу функцию-обёртку передавать один параметр-объект. В таком случае типизация будет ещё и очень простой.
А что, в дженерики в TypeScript специализацию завезли?
Generic в TS присутствует, но в следствии номинальной типизации решение на них будет мало чем отличаться от перегрузки с кучей не обязательных параметров.
К примеру вариант Sum, но не для простых типов, а скажем для Point и Vector это превратится в такой же If с анализом типа, а если типов объектов будет больше то и код разрастётся.
В целом TS хорош, и против Js это огромный шаг вперёд. Но так как это всего лишь надстройка, многие вещи реализованны крайне не удобно
Не очень понял вопрос, что за специализация?
Я говорил про что-то вроде такого:
const claim = <T extends Params1 | Params2>(params: T): T extends Params1 ? Return1 : Return2 =>{
// ...
}
Я про плюсовый финт ушами: когда есть, допустим, шаблонная функция (с неизвестным типом аргумента T). И тут вы пишете ещё две – для T==int и T==string. И компилятор сам везде подставит нужную (благо, никакой разбор типа аргумента в реалтайме не нужен, типы известны на этапе компиляции). Никаких if в теле функции, никакого оверхеда. Просто две функции с одинаковым именем.
а, это было бы хорошо (наверное :) )
TS это проверка типов на этапе компиляции. В рантайме там обычный JS. Поэтому перегрузка типов функции есть, а перегрузки функций (aka ad-hoc polymorphism) нет. Чтобы это сделать нужно заниматься кодогенерацией. Но реализовать такую фичу не так просто как кажется.
Как получить тип первой перегрузки ?
Перегрузка функций в TypeScript