Pull to refresh

Comments 139

По опыту скажу что эконимия времени с ts существенная.
Убрали свойство класса, и во всех местах, где это свойство используется подсветилось красненьким.

Подсветили — это ерунда (толку, если так в миллионе файлов?), вот автоматический рефакторинг — куда более серьезное преимущество.


Я как-то потерял обязательное свойство объекта в длинной (очень) цепочке rxjs-операций, и компилятор Typescript сразу же указал на ошибку. Ручками я бы такое отлаживал полчаса минимум — да и не факт, что вообще заметил бы.

Я гадаю, что плохого люди находят в динамической типизации?
Я бы после этих слов увольнял бы такого разработчика. То есть он вообще не видит минусов у динамической типизации.

Я полагаю, идея автора в том, что динамическая типизация обладает не только минусами, но и плюсами. Причем последние уравновешивают первые, иначе не было бы языков с динамической типизацией. Автор несколько раз в разных формах возвращается к тезису "зачем добавлять типизацию туда, где ее по задумке (нарочно) не добавили? Почему просто не использовать язык со статической типизацией?".
П.С. Я бы проголосовал за то, чтобы радикалов "увольняющих" людей основываясь на собственных домыслах не допускали к принятию подобных решений. Делать вывод о том, что автор не видит минусов в динамической типизации, на мой взгляд, сильно поспешно в данном случае.

Я специально выделил слова, где автор искренне недоумевает в наличии хоть каких-то минусов у ДТ. А ЯП с ДТ имеют место право быть в своей нише. О чем никак автором не указано.
А потом удивляемся, почему ПО часто не торт — просто радикалов мало в менеджменте.
ПС: Хотя я не знаю, что наносит больший вред — глупость разработчиков или жадность менеджеров.

Как по мне, автор не понимает разницы между слвбой-сильной и статической-динамической типизацией. И в этом и состоит его, автора, проблема. Динамическая типизация имеет и плюсы, и минусы. А вот плюсы слабой типизации мне вообще как-то неочевидны.

UFO just landed and posted this here

Прежде всего простота разработки интерпретатора/компилятора.
И, пожалуй, простота написания простого кода.

UFO just landed and posted this here

Под словом "простой" стоит понимать не количество кода, а низкую запутанность (или по англ. low complexity) кода.


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

UFO just landed and posted this here

Вот как проверить опечатку, например, в переменной окружения? Не перекомпилировать же все имеющиеся в системе скрипты каждый раз.


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

UFO just landed and posted this here
Решение может быть в формировании дополнительного модуля...

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


А все для того что бы решить такую простую задачу, как например, запустить сервис с некоторыми аргументами. Где сервис и так сам проверяет входящие параметры и выдает ошибку в случае не корректного аргумента.

UFO just landed and posted this here
UFO just landed and posted this here
Мне неочевидно, что потребность в рефлексии прямо следует из статической типизации.

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

Хотел в качестве примера привести один из своих сервисов с Protobuf и кучей рефлексии на бэкенде, и полным ее отсутствием на фронтенде. Но потом осознал, что я использовал TypeScript на фронтенде. Просто TypeScript, с его утиной типизацией и объединением типов, оказался значительно более гибким, чем C#

UFO just landed and posted this here

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

UFO just landed and posted this here
А что диспетчер с ними делает?

Это не важно. Основная необходимость в рефлексии тут только для того, чтобы иметь возможность десериализовать произвольное Protobuf сообщение. Поскольку, в отличии от JSON, данные переданные через Protobuf можно десериализовать только при помощи парсера соответствующего сообщения.


По этому, вместе с самим сообщением отдельно строкой передается его тип. А чтобы сопоставить тип с его парсером нужна либо рефлексия, либо какой-то автоматически генерируемый словарь парсеров.


Ну вот: вы уже знаете, что в объекте есть некоторое поле. Скорее всего вы знаете структуру метаинформации. Это всё вполне можно типизировать.

Каким образом, если они генерируются сторонним приложением? Они, конечно, создаются как partial классы, но вручную допиливать автоматически генерируемые классы мне кажется не самой разумной идеей.

По этому, вместе с самим сообщением отдельно строкой передается его тип. А чтобы сопоставить тип с его парсером нужна либо рефлексия, либо какой-то автоматически генерируемый словарь парсеров.

Рефлексия как замечено тут не нужна. Можно просто сделать функцию которая так и будет парсить


fn deserialize_any(message: Message) {
  match message.tag {
      "ClassA" => parse_a(message.body),
      "ClassB" => parse_b(message.body),
      ...
   }
}

Где конечно же deserialize_any, parse_a и parse_b генерируется во время сборки.

Не уверен что значит "генерируется во время сборки". В .NET Framework есть какой-то свой механизм мета-разработки, который на лету позволяет генерировать компилируемый код? Можно подробнее про это?


Если же речь про написание своего плагина к protoc, то, увы, этот вариант не подходит, так как либо потребует распространения бинарника, либо сильно усложнит использование библиотеки сторонними пользователями.

Не уверен что значит "генерируется во время сборки". В .NET Framework есть какой-то свой механизм мета-разработки, который на лету позволяет генерировать компилируемый код? Можно подробнее про это?

Есть, берете рослин и вперед :)


Вот например один из моих генераторов во время сборки генерирует рест-клиент для WCF апи:
https://github.com/Pzixel/RemoteClient.Roslyn


Или вот я генерируют сишарп-типы из солидити чтобы делать запросы в блокчейн:
https://github.com/Pzixel/Solidity.Roslyn




В более подходящих для этого языка есть более стандартизованная кодогенерация на макросах.

Немного смущает наличие Visual Studio требованиях и возможные проблемы с .NET Framework 4.5.2. Но в любом случае спасибо, посмотрю.

Эмм, тут от студии ничего не требуется, оно работает на основе DotNetCliTool.


Студия не нужна, msbuild спокойно сгенерирует всё. Правда начиная с какой версии не берусь судить.


Но и 452 это уже довольно старая платформа. Мы вот например с неткора 2.0 на 3.1 хотим до лета переехать)

UFO just landed and posted this here
Либо экзистенциальный тип.

Можете привести пример как это может выглядеть в C#? Хотя, видимо, в любом случае это потребует дополнительной генерации кода, что не приемлемо в моем случае.


А, сторонее приложение не даёт эту информацию в типизированном виде?

В частности, стороннее приложение, это Protocol Buffer: C#. Так что да, его встроенные средства не позволяют обобщать типы и не генерирует словарей парсеров.


Хотя он и генерирует мета информацию о сгенерированных типах, под капотом там все равно все тот же самый
System.Reflection.


Тогда да, это проблема (но проблема стороннего приложения, а не типизации).

Я согласен с этим, но в реальном мире мы часто имеем дело со сторонними приложениями и библиотеками, которые не можем контролировать.

Хороший тайпчекер требует вывода типов для хорошей эргономики.
Касательно простоты — для меня простой код, который я могу держать в голове, заканчивается строках на пятиста примерно. Дальше уже явно дискомфортно. Но я не показатель т.к. в динамику сунулся уже после статики.

UFO just landed and posted this here
Завидую.

Ну я же не уточнил, сколько таких кусков я могу вообще держать в голове :) Больше одного за раз не влазит, потом приходится голову проветривать. Плюс показатель сильно падает если он нарезан на несколько файлов… Короче сильно много "если". Рассматривайте эти 500 как идеальный случай несложного кода, мной же и написанного.

по задумке (нарочно) не добавили?

По задумке Javascript не создавался для больших сложных SPA

ну так пишите свои "большие и сложные" на своей джаве!
Я вообще не понимаю, все ведь уже было "достигнуто" говорителями про держание вселенной на своих плечах?
DOM по спецификации может быть написан на чём угодно вообще, так где джава, пайтон и т.д. реализации ДОМ !?
Такие превеликие титаны джавы со всеми своими "специально для интернета рожденными" сервлетами и апплетами и JSP и JSF смогли родить в сухом остатке продукта недо-лендинг на прайм-фэйс за овер 250$ за страничку в трех вариантах дизайна, но без респонзивности (но потом подвезут... когданибудь)

Только трындеть ООП-щики и могут, про то как сферические кони бороздят большой вакуум их мега-гигантских и сверх-нагруженных непонятно чем и зачем супер-приложений которых никто не видел а кто видел говорит что они все на одно лицо и это лицо хоумпэйджа гугл!

Им никогда не до этих ваших мелочей про юзабилити и котиков с изюминкой, они думу-думают про OM которой будет тесно в этой вселенной и которая удовлетворит всех и навсегда!

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

Просто ответьте себе предметно и честно, как и почему ДОязыки слили и рипнули перед этим недо- !?

Почему просто не использовать язык со статической типизацией?

Почему же не использовать? Использовать — TypeScript. Во фронтенде, к несчастью, не так много вариантов.
UFO just landed and posted this here

Отсутствие затрат на поддержку типов.

То есть о курице вы будете заботиться только о той части, что яйца несет?
UFO just landed and posted this here
Почему просто не использовать язык со статической типизацией?

Ответ на этот вопрос предельно прост: потому что популярные браузеры не поддерживают никаких других языков кроме JavaScript.


Конечно же, вы можете сказать: а как же WASM и бесчисленное множество транспайлеров из других языков? WASM, за редким исключением, пока что не готов для использования в боевых проектах, а транспайлеры все так же на выходе выдают JavaScript. Только в отличии от TypeScript, все остальные популярные транспайлеры не имеют такой богатой базы описаний типов других библиотек и прямой совместимости с JS. Да еще и часто тащат с собой тяжелый рантайм.


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

UFO just landed and posted this here
Я на статически типизированных языках ни разу не встречал бага вроде «вызвали функцию не с тем числом аргументов после рефакторинга», или «вызвали функцию не с теми типами аргументов, когда их порядок или тип поменялся после рефакторинга», и так далее. На питоне я не раз видел падения из-за подобного рода ерунды в проде.
Т.е. если ДТ позволяет накосячить, и люди косячат, значит виновата ДТ?
UFO just landed and posted this here
«Виновата» — возможно, не самое подходящее слово
Тут да, я погорячился. Я всё же сторонник того, что всему своё применение. ДТ снижает для меня то, что некоторые называют friction, т.е. мне просто приятнее и легче с ним, я скорее потерплю минусы ДТ ради этого. СТ я готов терпеть ради производительности в компилируемых языках.
UFO just landed and posted this here

На Си подобные ошибки встречаются, а уж от порядка аргументов спасёт только отдельный тип для каждого.

UFO just landed and posted this here

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

Ада, Паскаль, Фортран, Кобол, Алгол — они все статические, появились до C. Динамические появились гораздо позже.

Лисп появился практически одновременно с Фортраном. Про Фортран как-то не подумал, что он со статической, как-то тот диалект на котором писал когда-то относил к безтиповым что ли. А вроде не просто конвеншн был как-то разделять именами числа и строки, а что-то помощнее.

UFO just landed and posted this here

Даже если так (для меня не факт), то Си определенно образец с моей точки зрения — очень многое просто скопировано в системы типов других современных популярных языков как статических, так и динамических.

Есть хорошая статья Sharp Regrets: Top 10 Worst C# Features, где один из дизайнеров языка прямо говорит "мы сделали такое поведение, потому что так в си, а зря".


Синтаксис указателей и спиральное вычисление типов например по сравнению с паскалем страшные совершенно.


Будь паскаль чуть менее вербозным: со скобочками вместо begin/end например, думаю он был бы намнооого популярнее.

UFO just landed and posted this here
UFO just landed and posted this here
Я всё силюсь понять, а как можно рефакторить так, чтобы поменять сигнатуру функции, и не поменять все места, где она вызывается? Это же очевидно, что что-то сломается, если так сделать.
UFO just landed and posted this here
Может, отвлекли во время грепа человека
Короче, видимо и правда опасно с ДТ писАть в таких условиях. Меня не отвлекают, к счастью.
UFO just landed and posted this here

Например, вызов вообще неявный.

Тут вопрос нужно ставить по другому: действительно ли был нужен ts вообще? Или большинство людей тупо разучились (или не умели никогда) писать код и думать головой?

Сложность современных фронтов (пускай и отчасти искусственная) уже не позволяет держать в голове все сигнатуры, а TS позволяет оперативно выявлять часть ошибок. Особенно заметна польза при широком использовании ФП подходов.

Соглашусь. По опыту начинали писать на чистом js, багов было тьма. С перехом на ts количество багов заметно снизилось, проще говоря они возникают на уровне логики или при взаимодействии с сервером. На чистом js чаще ошибки чаше на уровне структур, манипуляции данных(например при изменении параметров метода). Скорость кодинга возрасло, типизация упоощает реализацию intellisense. А про фичи, которые на js можно применять через пару лет, ts ускоряет внедрение. Чего стоит только операторы .? или ??.. Слюньки текут)
элвис и нулиш коалесцинг итак давно не только в бабеле но и в браузерах

А почему вы не ставите под сомнение необходимость того же JS? Там же куча лишнего — какие-то массивы, объекты, сборка мусора. Писали же раньше люди без всей этой ерунды на ассемблере. Или


… большинство людей тупо разучились (или не умели никогда) писать код и думать головой?

Если же без ехидства, типизация, как и ООП, ФП, сборка мусора призвана перераспределять сложность и снимать часть когнитивной нагрузки с человека, заменяя её автоматизированной машинной проверкой. JS был изначально создан для простеньких эффектов типа снежинок на странице — а не для современных сложных страниц-приложений. Вот как и в случае с ассемблером и к примеру С++, стали делать абстракции над ним, решающие проблему сложности в тех или иных случаях.

И много вы сложных современных страниц приложений написали?

Я лично — ни одной. Я С++ник. Мне на ЖСе вообще некомфортно писать. Но видел пару раз вблизи довольно сложные проекты, которые ради поиска тривиальных проблем, проверяемых тайпчекером, обмазывали тестами по самое немогу.

Экспертное мнение на высоте :)

Как по мне, у меня вполне хватает информации для такого вывода — исходя из истории создания JS Бренданом Айхом, набора изначально вложенных в него концепций, набора "артефактов" вроде странностей слабой типизации. У меня есть с чем сравнить из динамики — я гораздо плотнее работал с Lua и Python.

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

Ещё стоит не забывать о группе людей с малым опытом в разработке. Турескрипт неплохо помогает на кодревью отпустить вожжи, чтобы не парсить глазами весь код, в попытке словить очевидные ошибки по невнимательности, которые они там накоммитили

Автор делает несколько утверждений типа "я не вижу", "я не понимаю", а, "подводя итог", делает вывод о языке, а не о своих способностях. Странно.

Мое мнение, typescript нужен, он позволяет переложить часть данных из головы прогера на язык. Тем самым прогер не держит в памяти все контракты функций, методов и тд, а держит там вещи более полезные.
Лично я начал пользоваться typescript'ом и больше не хочу возвращаться на js, только если сайтик простой делать и там кода на 500-1000 строк.
Читабельность которую автор показал — это дело вкусовщины.
Также в статье есть моменты, где автор указывает, что приходится больше писать, но это минус? Я бы лучше читал более подробно описанный код, пусть даже слегка многословный, чем красиво оформленный, но краткий. Автор также ставите в пример новичков, но им как раз и нужно понять как работает, и тогда, на мой взгляд лучше длинный, понятный код.
И что лучше, если новичку укажет язык, что он не то передает? Или чтобы что-то свалилось в рантайме, а он этого не заметил и выкатили на прод?
Да, typescript далеко не все ошибки видит, но часть проблем он снимает с разработчика. А ошибки в любом языке можно сделать.
Плюс автор пишет:
Окей, мы больше не хотим Java, хотим JavaScript. Но нам не нравится JavaScript таким, как он есть, поэтому давайте сделаем его немножечко более похожим на Java. Отлично, теперь у нас есть все, что было в Java, при этом это не Java. Погнали!

А что плохого в этом? Автора же не заставляют переходить на ts. Любой язык имеет свои особенности. Кому-то нравится js, кому-то c#, а кто-то хочет во фронт, но с c# и берет ts) все хотят свою машину, посмотрите на город, у многих разные они, спрос — предложение. Считали бы люди по другому, не было бы сейчас ts.
Да и сообщество положительно реагирует, он стал довольно быстро растущим языком. Он многим нравится. Сообщество делает выбор, если вам не нравится идея ts, то делайте свой выбор. Вам никто не запрещает.
А может мы просто его не осознали и сейчас все обманываемся, такое тоже может быть)

Ps. Повторюсь, js классный язык, как и любой другой, но лично мне больше импонирует ts. Но каждый человек выбирает себе сам, но статья больше похожа на агитацию к js, и по ощущению, автору обидно что ts сейчас довольно популярен и его все пиарят. А автору нравится js, он видит что не все так хорошо в ts и нападает на него из-за этого, потому что не приятно быть в меньшинстве… хотя кому как…
Ps 2. Не судите строго всю эту писанину… может я вообще не прав и это сон собаки

Поставил плюс хотя я не сторонник ts.


P.S.
Автору статьи: если на js оказала влияние java, то на ts повлиял C#.

TS разрабатывал тот же человек, что и C#, если память не изменяет.
то на ts повлиял C#
Учитывая, что один из основных авторов — один (как у и Delphi) то совсем не удивительно.
TS — это лучшее, что случилось с JS со времен начала его использования.

А что плохого в этом? Автора же не заставляют переходить на ts. 

Сообщество делает выбор, если вам не нравится идея ts, то делайте свой выбор. Вам никто не запрещает.

Вспоминая, какие корпорации стоят за тайпскриптом, напомнило "Тебе не нравится политика цензуры нашей многомиллиардной соцсети? Иди делай свою и сиди там, тебе никто не запрещает, хехе!"

автору обидно что ts сейчас довольно популярен и его все пиарят.

Может, автору обидно, что разработчиков, которые нормально справлялись и справляются без этой подпорки, у которых нет постоянных проблем с типизацией, открыто считают унтерменшами? Вот даже здесь в комментах орут "Да я б немедленно увольнял его, пусть попробовал бы заикнуться, что динамическая типизация хорошо".

Мне вот не нравится загромождение кода. У меня нет настолько частых ошибок с типизацией, чтобы настолько раздувать код. Да, я работаю с БАЛЬШИМ И СЛОЖНЫМ проектом. Но если эту "новую Java" будут требовать в каждой вакансии, деваться будет некуда - придётся кушать и просить добавки. Хорош "свободный выбор", правда?

Что значат все эти дженерики?

Ctrl+Click обычно помагает.


… у них отличная команда поддержки и документация. Но что, если нам придется поддерживать код, который не имеет всего этого?

Если в них нету документации тогда в случаи с JS мы вообще не знаем что такое dispatch, тогда как в случаи с TS знаем все интерфейсы (+ IDE помогает)


И для ThunkAction<void, {}, {}, AnyAction> и ThunkDispatch<{}, {}, AnyAction> можно сделать псевдонимы типа AnyThunkAction AnyThunkDispatch если они очень часто используются.


Первое, что бросается в глаза — опять пишется больше кода.

userRoute.ts может виглядет так:


class UserRouter extends Router {
    public address = "/users";

    list(req: express.Request, res: express.Response) {
        //get uesrs from DB
        res.json(users);
    }

    create(req: express.Request, res: express.Response) {
        //create user
        res.json(userCreated);
    }
}

Например так выгладит хендлер для CRUD в Python/Django REST Framework с авторизацией, пагинацией, автогенерацией документации и еще много чего (подскажите аналог для TS/JS):


class UserViewSet(ModelViewSet):
    serializer_class = UserSerializer

Где здесь лишний код из за ООП?


П. С.: Лично для меня идеально не писать типы, но чтобы IDE о них знала. В Kotline что-то такое делают.

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

Пишу на JS, при этом использую статический анализ от TS. Мой код может работать в браузере без транспайла, писать тесты и дебажить — одно удовольствие. Я не делаю глупых ошибок, у меня подсвечивается все как нужно и проверяются типы. Что я делаю не так?

а это как? можно ссылку на какой нибудь пример или на статью?
К примеру, если вы используете VS Code, вы можете добавить в начале вашего js-файла:
// @ts-check

Либо эту опцию можно включить для всех js-файлов по умолчанию (рекомендую). Это можно сделать в настройках воркспейса либо глобально во всем редакторе. После чего, вы сможете использовать аннотации типов в формате JSDoc:
/**
* @param {Object} src
* @param {String} src.uid
* @param {Number} src.date
* @param {String} [src.detail] необязательный параметр
*
* @returns {String}
*/
function myFunction(src) {
  ...
};

Существует и более компактный формат, но за нюансами — лучше сходить в доки.

В любом месте использования вы будете видеть сигнатуру вашей функции и ошибки при попытке сделать что-то неправильно. Ну и так далее: примитивы, пользовательские типы, все что нужно будет проверяться и подсвечиваться. Далее вкусовщина — на мой взгляд, аннотации в формате комментов делают сам код более чистым и читаемым в части логики. А главное, он работает в браузере в исходном виде. После того как привыкаешь — код на TS кажется излишне замусоренным и избыточным.

Спасибо за ответ, вспоминаю где-то подобное читал и забыл напрочь. Думаю самое то, код остаётся чистым и есть проверка на тип. Вери Гуд!

Я не делаю глупых ошибок

Честно, завидую.

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

Второй пример ещё более не корректен, ts не заставляет переписывать код на классы, наоборот ts стремиться поддерживать все паттерны распространенные для js.
Первый вариант как раз неплохо показывает, что на TS нормально описать типы — та ещё задачка.

Ну это скорее проблема reduxa, видно что он не проектировался с учётом будущей типизации

UFO just landed and posted this here
А код который передает и строку и объект в одной переменной, на мой взгляд, плохо пахнет и имеет признаки непродуманного дизайна.
Велкам в динамическую типизацию (которая ортогональна сильной, конечно же, автор статьи их путает). В питоновском коде, что мне встречался — то такое сплошь и рядом. Одна переменная — и в ней все данные функции вообще: люди, кони. Ну так разрешено же. После Delphi, конечно, смотрится как дичь.

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


...
responseHandler (obj) {
  return {
    name: obj.username || obj.user,
    isAccepted: obj.isAccepted || (obj.accepted === 'yes' || 'nope'),
    ...
  }
}
...

это ужасный код приносящий душевные травмы.

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

Так строго типизированный TypeScript как-раз позволяет это делать при помощи union types и type guards. И я бы не назвал это непродуманным дизайном. На мой взгляд, как альтернатива перегрузкам функций это работает весьма неплохо и нисколько не мешает статической типизации.

Так TS никак не запрещает передать строку\объект в одной переменной.
UFO just landed and posted this here

Даже с таким супер-профи есть одна мааленькая проблемка. Людям свойственно совершать ошибки.

Вы здесь намекаете на то, что неплохо бы прикрутить статическую типизацию, чтобы меньше их совершать?

Потому что вообще говоря лучшее лекарство от ошибок — как раз концентрация.

Пожалуй да.


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


В чём-то аналогичная ситуация с шаблонами С++ для случая параметров-типов. До появления концептов проверять соответствие переданного типа некоему контракту делалось с помощью определённых трюков. Причём реальное использование одного из элементов контракта могло происходить глубоко во вложенных шаблонах. И тогда вы получали длиннющий (несколько десятков, а иногда и сотен строк) и малочитаемый отчёт об ошибке, которая возникла почти наверняка совершенно не в том месте, которое её вызвало.


Так что концентрация не панацея — ресурсы мозга ограничены. Абстракции в виде ООП, ФП или типизации призваны перераспределять сложность, снимая часть когнитивной нагрузки с человека. Если бы всё было так просто, как вы пишете, до сих пор писали бы в машкодах. Чё там, сконцентрируйся — и никакие эти ваши абстракции не нужны.

А как в описываемых вами системах отлавливают логические ошибки? Типа неправильного коэффициента в уравнении, записи не в ту переменную, забытого инкремента?

Мне вот реально интересно, потому что большинство ошибок у меня именно логические.

А я разве где-то сказал, что типизация это панацея? Типы ловят вполне конкретный класс ошибок. Касательно приведённых вами примеров с преимущественно математикой — можно к примеру закодировать типами единицы измерения. Тогда вы сможете гарантировать на этапе компиляции что у вас результат будет м/с^2, а не кг/Н^2. От забытого инкремента или записи не в ту переменную длины это вас конечно не спасёт.


Но давайте представим, что код представляет собой не какой-то вычислительный алгоритм, пусть и сложный. А систему из, скажем, объектной модели документа, представленной сторонней либой. Плюс 3D представление на каком-нибудь OpenSceneGraph со своей иерархией узлов сцены. Плюс несколько панелей виджетов с разными представлениями в модель. Плюс менеджер выбора объектов. И тут у вас в модели документа при апгрейде в каком-то из объектов меняется набор полей… Представьте себе развлекуху отлавливать и править все места, где это используется.

можно к примеру закодировать типами единицы измерения.

Не про тайпскипт, увы, если не извращаться.

Там разве нельзя использовать типы-параметры как маркеры?

А я разве где-то сказал, что типизация это панацея? Типы ловят вполне конкретный класс ошибок.
А я с вами не то, чтобы спорю. Просто концентрация лично мне позволяет ловить и совершать меньше и ошибки типов, и логические. Пытаюсь понять, как у других.

А то, о чём вы написали, я скорее всего сяду, подумаю, и как-либо обвяжу, чтобы удобно с этим работать из своего кода.
А то, о чём вы написали, я скорее всего сяду, подумаю, и как-либо обвяжу, чтобы удобно с этим работать из своего кода.

Это вполне конкретный пример из проекта, с которым я имел дело. Проект на С++/Qt. Там объектная модель была полностью динамическая, но нерасширяемая никак. И как раз обвязка была статически типизированная т.к. авторы либы любили ломать что-нибудь даже в патч-релизах. Я не знаю, сколько бы заняла времени ловля подобных багов без статической обвязки.

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


Что интересно, многие на самом деле пользуются статической типизацией в динамически типизрованных языках, не подозревая об этом, если у них включены всяческие инспекции в IDE и они обращают внимание на предупреждения типа "в этом объекте такое свойство не объявлено".

Существуют еще более сильно-типизированные надежные языки, в которых можно например разделить высоту и длину и т. п., хотя они оба — integer. Например — Ada, вышедший из Паскаля:
progopedia.ru/language/ada
UFO just landed and posted this here
UFO just landed and posted this here

Чем более мощная и выразительная система типов в языке, тем большую долю логических ошибок можно превратить в ошибки типизации. Вплоть до полного «если программа скомпилировалась, то она 100% соответствует спецификации».

UFO just landed and posted this here

Частично уйдёт с поддержкой С++20. В мейнстриме оптимистично уйдёт лет через 5, реалистично лет через 10-15.

UFO just landed and posted this here

Да я в курсе. Но лучше такие волокуши чем совсем по грунту тащить.

UFO just landed and posted this here

Я как ни стараюсь концентрироваться, всё равно делаю ошибки, иногда глупые. Поэтому лучше возьму компилятор в помощники и стану концентрироваться на задаче, чем пойду увольняться по профнепригодности.

UFO just landed and posted this here
PHP от версии к версии движется в сторону строгой типизации.

Строгой, но не статической. Очень многие разницы не видят вообще, отожествляя "строгий" со "статический" и "слабый" с "динамический". При этом забывая по слабый статический C и сильный динамический Python и усиливающийся на глазах динамический PHP

В сторону статической типизации идет тулинг воркуг пхп, например psalm уже сейчас позволяет полностью покрыть программу типами и проверять их соответствие до запуска.
Статическая типизация дает и другие преимущества.
1. Когда компилятор точно знает все типы на этапе компиляции — он может лучше оптимизировать код.
В то время как строго типизированный TS все равно компилируется в JS — и в итоге компилятор не может ничего толком оптимизировать потому что ничего толком не известно.

2. Статическая типизация позволяет создавать очень мощные инструменты рефактроринга и статического анализа.
Именно по этому в мире Java/C# существуют ReSharper/IntelliJ и другие плюшки.
В то время как в мире JS — search/replace до сих пор является основным средством рефакторинга.

В третий питон добавили type annotations, кстати. Явно не просто так.

С ростом приложения все перечисленные минусы — многословность, явная типизация и лучшие практики — превратятся в плюсы. JS нормальный, многим хорошо на нём пишется, в том числе мне. Но TS предпочтительнее в проектах, где кодовая база, предполагается, будет быстро разрастаться. Тут появляются все плюсы: интеграция IDE, чтение сигнатуры чего бы то ни было, дебаг на этапе компиляции, удобный рефакторинг, улучшенные техники организации кода, удобство разработки в команде (для нас код на typescript более прост в изучении и сопровождении, чем javascript).

Так что пишите спокойно на JS. TS оставьте, если в нём нет надобности.
Не соглашусь с автором. Да, признаюсь я был таким же как автор, и с такими же взглядами. Когда появился TS я был против. Ну зачем, зачем еще какие-то надстройки? Если вы хороший разработчик, вам TS не нужен. Я действительно так думал и говорил.

Но пару лет назад я начал писать на TS, понемногу. Где-то с ошибками, где-то тупо в лоб с any. И сейчас, спустя два года, я полностью перешел на TS. На вопрос — почему, почему я кардинально изменил свои взгляды и мировозрение? Ответ прост — это просто удобно и приносит свои плоды. И сейчас я все свои проекты перевожу с JS на TS.

Самое большое удобство — это читаемость кода. Да, когда ты работаешь в команде из 10 человек. То понять код товарища — ой как сложно. И TS помогает понять и проанализировать что к чему. Следующее удобство — IDE. Приятно иметь быструю навигацию по проекту с подсказками и проверками. Поверте, для больших проектов это неоценимо.

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

По поводу читабельности кода. Приведу контроллер со своего TS проекта. Так как, то что привел автор — фигня какая-то.

@Injectable
@Controller()
class Word extends AppController {

  @Auth('user')
  @Get('/get/:id')
  async get(@Req() req: Request, @Param('id') id: string): Promise<IWord> {
    return await WordModel.getByUser(req.user, id);
  }

  @Auth('user')
  @Delete('/remove/:id')
  async remove(@Req() req: Request, @Param('id') id: string): Promise<IWord> {
    const word: IWord = await WordModel.getByUser(req.user, id);

    await word.remove();

    return word;
  }

}

export {
  Word
};

А что означают строки, начинающиеся на @?

Похоже, это декораторы, используются, например, в Nestjs.
Посмотрел NestJS по приведенному линку. Они используют такой же подход для написанию контроллеров, который я сделал у себя. Правда у меня это только обертка над ExpressJS. Но приятно, когда взгляды у людей совпадают :)
NestJs тоже обёртка над express :)
У них в описании указано, что можно указать, что использовать. По умолчанию ExpressJS, но так же можно указать Fastify.

Under the hood, Nest makes use of robust HTTP Server frameworks like Express (the default) and optionally can be configured to use Fastify as well!


Хороший подход :)

В ts еще много чего интересного:). Лично долго ждал оператора .? Пример выше это декораторы — позволяют многое. Напоминает атрибуты в c#.

Статья необъективная. В примере с thunk'ом сравниваются 2 разные функции. Так более справедливо:

const getUsers = () => 
  async (dispatch) => {
    try {
      const users = await APIService.get('/users')
      dispatch(successGetUsers(users))
    } catch(err) {
      dispatch(failedGetUsers(err))
    }
  }

и тоже самое на TypeScript:

// 1 раз на всё приложение:
export type AppThunk = ThunkAction<void, {}, {}, AnyAction>

const getUsers = (): AppThunk => 
  async (dispatch) => {
    try {
      const users = await APIService.get('/users')
      dispatch(successGetUsers(users))
    } catch(err) {
      dispatch(failedGetUsers(err))
    }
  }

Ещё не надо указывать тип для переменной users — TypeScript автоматически выведет тип на основе результата метода get. Продвинутый вывод типов и отличает TS от Java, где нужно писать BeanFactory beanFactory = new BeanFactory(). Второй пример c Express-сервером прекрасно работает с TS, не нужен там класс.
BeanFactory beanFactory = new BeanFactory()

Уже не надо
UFO just landed and posted this here
Действительно ли легче читается TypeScript код?

Да, потому что в примере на js 100% нужно читать доку, попробуй угадать, что нужно передать :)

Несмотря на то, что штат поддерживающих TS разработчиков в последние 2 года значительно разросся и окреп, и еще более массово минусует посты и комментарии «не уверовавших», продолжаю оставаться в теперь уже непопулярном лагере сторонников написания кода без статического анализа типов. Не подумайте, что не имею опыта работы с этим языком, или что мало читаю нахваливающих его статей и комментариев — вовсе нет, и крупные проекты были, и аргументы из сотен комментариев аккуратно сложены на весы. Но в сухом остатке TS лично в моем понимании — гирька на пару кило пользы, а вреда тащит на пуд.

Вот значимая польза:
— при наличии сложных моделей данных TS справляется лучше, чем JSDoc — типы занимают меньше места, могут быть многосоставными и более гибкими
— при использовании паттернов, скрывающих промежуточные результаты (ФП), либо функций, допускающих передачу параметров разного типа и возвращающих разнородные значения, TS определенно поможет предсказать результат
— при доработке легаси-проекта, в написании которого участвовали разного уровня разработчики, а качеству кода и стандартизации уделялось мало времени (таких проектов, к сожалению, подавляющее количество...), TS поможет быстрее понять, на что повлияют вносимые изменения.

А вот и значимый вред (тут буду чуть более подробным):
— увеличивается время до достижения качественного результата.
Разработка — процесс творческий, и от поступления задачи до качественного кода может быть множество этапов (проектирование, черновик-mvp, оптимизированный черновик, отрефакторенный условно-качественный код, качественный код после ревью). Бывает и такое, что «сразу идеал», а иногда приходится придумывать и тестировать на производительность несколько версий. А часто — еще затрагивать довольно много окружающего кода. TS заставляет в каждой из версий описывать типы, сочетать их с окружающими, и переписывать при рефакторинге. Иногда спасает «any». А еще чаще надоедает эта возня и пушится код, не доведенный до идеала.
— увеличивается кодовая база, которую нужно поддерживать
— ухудшается читаемость. Это личное, но мне действительно сложно интерпретировать TS-код, когда к привычным источникам информации (название переменной, название функции которая преобразует данные, проверка данных в рантайме, комментарии) добавляются еще источники (предполагаемый тип переменной, предполагаемое возвращаемое значение, ссылки на сложные типы, дженерики) и вместе с ними дополнительные символы (:<>). То, на что без TS тратил условный X времени, становится как минимум 1.5X, пока все разложишь в голове, отделишь кодовые символы от типовых, научишь мозг сосредотачиваться на полезной составляющей кода. В итоге от этой пестроты намного быстрее охватывает усталость. Со временем просто стал фильтровать это все, как «неизбежный шлак», стало чуть попроще, но не особо.
— разработчики, у которых «скомпилировалось», менее тщательно относятся к проверкам в рантайме. Поэтому при реальной работе, когда есть множество источников данных, количество багов из разряда «cannot read smth of undefined», «toLowerCase is not a function» и т.п. возрастает. Возможно, в ваших проектах было по-другому, в тех, где участвовал я, их было неприлично много (нет, не мной допущенных ;)
— комплексный рефакторинг усложняется на порядок.
Я не об «изменении нескольких параметров в объекте» или «изменении параметров в паре функций» говорю, а о многосоставных изменениях кодовой базы на несколько тысяч строк. Сам за карьеру программиста таких рефакторингов очень плохо спроектированных частей приложений осуществил не один десяток раз, и если без TS это занимало Y времени, то с ним по субъективной оценке — минимум 3Y. На каждый чих приходится переписывать кучу типов (а то ведь не соберется), и уже после сотни чихов подумываешь о долгосрочном отдыхе на Бали. Вообще за крупные архитектурные изменения берутся очень мало специалистов, дело это сродни разгребанию Авгиевых конюшен, но что-то мне подсказывает что плохо написанные TS-проекты останутся помойками навечно, потому что даже глубоко верующий в мощь тщательно описанных типов скорее всего разочаруется в них, когда нужно будет делать что-то крупное и желательно быстро, т.к. затрагиваемый код может ежедневно наращивать конфликты с другими задачами.
— для корректной работы весь код, включая подключаемые библиотеки, должен быть типизирован, иначе получается «лоскутное одеяло» — в одних файлах все в TS, в других много мест с «any». Да, многие библиотеки имеют типы или для них сделаны пакеты с типами (версии которых нужно вручную синхронизировать), но это только в последнее время, и то далеко не везде. А чтобы было везде — приходится создавать себе «работу на пустом месте», форкая библиотеки, либо создавая для них типы и дорабатывая по мере обновления этих внешних зависимостей.
— дополнительное время на обучение коллектива, составление правил кодирования типов и ревью их грамотного использования.

Что касается «значимой пользы» — я лично стараюсь писать код «прямым как топор»; без паттернов с неявными промежуточными результатами вроде `pipeRight(toLowerCase, first, getUserEmails)`, в которых где-то объект, где-то массив, а в итоге наверное строка; без многочисленных этапов преобразования данных; без длинных функций, которые разве что кофе не сварят; с проверками всех нужных типов в рантайме и обязательной валидацией поступающих извне данных. Возможно, у вас совсем по-другому, и плюсы перевешивают, но этот язык — абсолютно точно не для всех проектов, скорее для выборочных.

По минусам хотел ответить:


— увеличивается время до достижения качественного результата.

Если речь не про прототипирование какой-то совсем маленькой задачки, то типы скорее помогут, чем навредят. В типизированных языках я часто набиваю рыбу тупо в типах которые бросают unimplementedException(), организую их, и когда доволен результатом только начинаю реализовывать. Очень экономит время.


Многих спрашивал и сам пробовал оценивать, порог после которого типы начинают выручать — строк 500. Причем чем больше человек в типизированных языках привык работать, тем этот порог ниже.


— увеличивается кодовая база, которую нужно поддерживать

Честно — я сильно сомневаюсь, что тайпскрипт даст хотя бы 10% увеличения кодовой базы. Особенно если не писать километровые типы, которые вам и не нравятся я так понял.


— ухудшается читаемость.

У меня есть некоторые знакомые, которые не выдерживают подсветку синтаксиса в коде. Ну, отвлекает она их (по их же словам). Поэтому они сидят и смотрят черный текст на белом фоне, где их ничто не отвлекает. Если вам как и мне это кажется диким — то вы легко можете провести аналогию. Типы это тоже подсветка смысла — вот тут строка, а тут — такой-то класс. Для стороннего наблюдателя не связанного с программированием подсветка в IDE это просто непонятный калейдоскоп, но мы-то понимаем сколько на самом деле в этом смысла.


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


const fmap = <A, B extends A>(f: (A) => B, a: Array<A>): Array<B> 
  => 1000 строк нечитаемого кода

Нежели из


const fmap = (f, a) 
  => 1000 строк нечитаемого кода

— разработчики, у которых «скомпилировалось», менее тщательно относятся к проверкам в рантайме.

Ну а это уже явно говорит о том, что вы злоупотребляете any или просто врете в типах. Тут схема примерно как с прививками — если 99% кода имеют типы (населения привито), то рантайм ошибки (болезнь) изолированы, но если эта цифра падает ниже определенного порога, то количество ошибок растет взрывообразно.


image


В таком случае вы платите тем что вынуждены писать типы, но не получаете ожидаемой выгоды из-за несоблюдения гигиены. Сразу становится понятно, почему вы в этом не видите особой ценности.


— комплексный рефакторинг усложняется на порядок.

Ну а тут я вас совсем не понимаю :) У меня совершенно диаметрально противоположенный опыт — без типов чихнуть боишься, не говоря про какой-то масштабный рефакторинг. Когда из тулов для рефакторинга только греп и внимательность, начинаешь к этому относиться "кабы чего не вышло" и "Работает — не трогай". С типами как раз наоборот — сделал рефакторинг, починил ошибки компиляции — код работает.


В общем, с примером какая проблема возникла и почему на ТСе пришлось все переделывать было бы очень кстати.


Что касается «значимой пользы» — я лично стараюсь писать код «прямым как топор»; без паттернов с неявными промежуточными результатами вроде pipeRight(toLowerCase, first, getUserEmails)

Обычно такие вещи появляются, когда однотипный код, отличающийся только toLowerCase/toUpperCase, first/last, getUserEmails/getUserNames, начинает попадаться очень уж часто и начинает мозолить глаза. И вынести это в одну функцию лучше, чем везде копипастить, в большинстве случаев.

Если человек привык именно к типизированным языкам — разумеется, он привыкает и к дополнительным источникам получения информации, и к синтаксису, нарабатывает удобные методы прототипирования в условиях 99% типизированного кода, учится полагаться на предупреждения компилятора, а не изучение кода и собственную внимательность.
Я же полтора десятка лет работаю с нетипизированными языками, и описал, с какими сложностями столкнулся вместе с командами фронтенд-разработчиков при попытке создавать SPA на TS. К сожалению, не вижу возможности провести достаточно достоверное исследование по параллельной разработке одинакового приложения на JS/TS, чтобы замерить скорость выполнения задач и качество итогового продукта — здесь практически все зависит от опыта разработчиков, а не используемых языков.
Поэтому в холиваре на заданную тему участвую редко, и опираюсь только собственный опыт, в котором внедрение типизации принесло намного больше вреда, чем пользы. Удивляет, что когда достаточно аргументированно делюсь опытом, стоившим не один миллион денег компании в виде увеличения сроков поставки, расходов на разработчиков и техсап, а также репутационные потери, почему-то получаю минусы в карму. Нет коллеги, я не покушаюсь на вашу веру, а вношу посильный вклад в развитие сообщества, которое вполне вероятно придет к выводам, схожим с моими. Либо научится преодолевать те сложности, которые я описал.

Вернул сколько мог обратно. Спасибо за комментарий, лично мне было очень полезно.


Я ни в коей мере не покушают на ваше мировоззрение, все же все люди разные, и кому-то хорошо с постоянной памятью но плохо с оперативной — такие люди выигрывают от того что знают монады/функторы, которые позволяют экономить на количество нюансов в текущем контексте, и наоборот — им тяжело запомнить все эти типы, но зато они сотни строк в голове удерживают.


Но мне кажется, что второй подход плохо масштабируется. В нетипизированном языке пара десятков человек на одном проекте кмк сделают ад.


Поэтому я написал свою точку зрения, что минусы ваши немного странно выглядят, особенно рантайм ошибки "undefined is not a function" в языке, где он запрещен и чтобы его получить нужно именно что специально забить на типизацию.

Подобные ошибки характерны, если в приложении нет тщательных валидаций, а это подавляющее большинство проектов. В типах может быть все прекрасно, а АПИ бэкенда отдало null в обязательном параметре, или number в id одного из элементов массива вместо строки, либо со стороннего сайта прилетел параметр с некорректным типом, либо непредсказуемо (а в JS такое частенько) сработало приведение типов — и вот в хранилище совсем не то, с чем может справиться статический анализ.

Во фронтенде много источников данных, а большинство архитектур построено таким образом, что возникающие непредсказуемые ошибки не изолированы в отдельных контекстах, а выскакивают в глобальный unhandled exception и рушат приложение полностью. Спасает от этого архитектура с тщательной валидацией + изоляцией сред выполнения со стратегиями отказоустойчивости + проверкой типов в рантайме непосредственно в функциях. Статический анализ тут абсолютно бесполезен, он оперирует «вероятными» типами и никак не освобождает от того, что писал выше.

При этом и не мешает сделать все хорошо. Я написал в недостатки, что типизация иногда расхолаживает разработчиков, которым становится лень описывать типы 4 раза: в TS, в рантайме, в валидации, в названии переменной (я сторонник более явных названий переменных, например не list, в котором может быть что угодно — array, collection, map, set и т.п., а listArray, listObservableMap). Конечно, забота старших разрабов следить за исполнением стандартов кодирования и качества в конкретных проектах, но тенденцию к расхолаживанию я замечал.

Благодарю за карму, настроение улучшилось!

P.S. По поводу масштабирования — гарантом единообразия кода и его качества являются стандарты + контроль их соблюдения. Сам язык или наличие типов никак не влияют на то, что 10 разработчиков будут писать непонятный друг другу код разного уровня качества. На памяти уже два случая, когда после увольнения разработчика остальным приходилось переписывать его код, так как он был им непонятен, и один из этих случаев как раз в TS-проекте. Но это камень в огород тимлида (эх...), который тогда не уделял должного внимания стандартам и приведению навыков команды к общему уровню методом публичного обсуждения проектируемых каждым решений.
В типах может быть все прекрасно, а АПИ бэкенда отдало null в обязательном параметре, или number в id одного из элементов массива вместо строки, либо со стороннего сайта прилетел параметр с некорректным типом, либо непредсказуемо (а в JS такое частенько) сработало приведение типов — и вот в хранилище совсем не то, с чем может справиться статический анализ.

Ну так для этого же есть валидация по схеме) Я когда-то интересовался, вот интересный проект, вроде есть и другие. Всё, что прилетает из недоверенных источников (по сети) предварительно валидируется. Очень сильно помогает жить. К слову, не важно, жс или тс, чем раньше к месту ошибки упасть, тем легче потом чинить.


Статический анализ тут абсолютно бесполезен, он оперирует «вероятными» типами и никак не освобождает от того, что писал выше.

Вы всегда оперируете типами, просто они не всегда явно выражены в коде. Например когда вы пишете a + b вы предполагаете определенную логику. Если вместо чисел или строк вдруг пришло два промиса, то складывать их вы вряд ли хотели.


Типы это не обязательно "юзер" или там "строка", иногда это "что угодно что умеет складываться"


trait Addable {
  fn add(self, other: Self) -> Self;
}

При этом и не мешает сделать все хорошо. Я написал в недостатки, что типизация иногда расхолаживает разработчиков, которым становится лень описывать типы 4 раза: в TS, в рантайме, в валидации, в названии переменной

Ну описывать 3 раза тоже фигово. Я выше тулзу скинул, по идее она позволяет сразу получить и типы, и валидатор этих типов для внешних источников. Вроде есть и другие (например, typescript-json-schema + ajv). Я тут статью последнюю переводил, там как раз про то что типы — это не всегда про боль и много-много лишнего текста чтобы компилятор остал.


Благодарю за карму, настроение улучшилось!

image

Я бы еще добавил, что помимо полного отказа от any нужно еще и включать режим strict в tsconfig.json, только тогда будет почти полная гарантия отсутствия "undefined is not a function" и аналогичных ошибок в райнтайме.


"Почти", потому что есть одна дыра в TypeScript, которая рушит всю типо-безопасность даже с максимально строгой проверкой и без использования any.

Я может быть единственный в мире такой человек в чем я сильно ошибаюсь, но я ни разу за 6 лет не словил бага связанного с типизацией. 99% багов связаны с ошибкой в логике, когда что то не учел. И писать +100500 строк кода ради какого то мифического отлова багов это треш.

Тоже самое и про redux. История 1 в 1 как с typescript.

Работал на 2х проектах в двух банках, в зеленом и синем. У зеленных был mobX и не было typescript, у синих typescript и redux. Проекты сопоставимы по размеру. В итоге лапша из кода в обоих проектах, но с typescript и redux в 2 раза больше кода и увеличенные требования на вход в проект из за typescript и redux. Плюс тратишь в 2 раза больше времени на написание.
И вот вы мне объясните для чего я должен тратить в 2 раза больше времени на написание кода вместо того чтобы потратить это время на написание новых фич?

Мое мнение никакого typescript и redux, а mobX + код ревью. А если учесть что еще код тестами покрывается, то typescript вообще тупость полная.

Sign up to leave a comment.

Articles