Pull to refresh

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 она выглядит слишком монструозно и несуразно, что как будто бы весь смысл использования высосан из пальца и проще просто использовать разные имена

В ts она абсолютно понятна, если рассматривать его, как обвязку над js, не дающую вам наступать на грабли.

Дело в том, что уже есть куча функций, возвращающих разный результат в зависимости от аргументов (e.g. chrome.tabs.query), и их надо как-то типизировать, чтобы не было мучительно больно.

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

А что, в дженерики в TypeScript специализацию завезли?

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

К примеру вариант Sum, но не для простых типов, а скажем для Point и Vector это превратится в такой же If с анализом типа, а если типов объектов будет больше то и код разрастётся.

В целом TS хорош, и против Js это огромный шаг вперёд. Но так как это всего лишь надстройка, многие вещи реализованны крайне не удобно

Да когда у нас проект с js на ts перевели – я готов был плакать от радости ..

Не очень понял вопрос, что за специализация?

Я говорил про что-то вроде такого:

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) нет. Чтобы это сделать нужно заниматься кодогенерацией. Но реализовать такую фичу не так просто как кажется.

Как получить тип первой перегрузки ?

Sign up to leave a comment.