Ааааааа... Опять увидел обсуждение тс vs флоу. Конечно не смог пройти мимо и хотел было как обычно устроить срач, но не смог: желудок предательски проурчал слово "шаверма".
Многие считают, что typescript это спасение всех жсеров от ошибок, но любой умный человек, пишущий на флоу, понимает, что дело совсем не в типизации. Дело в мемкрософт.
На деле же, с тс немного проще начать писать новый проект (не на реакте конечно). В тс хорошие тулзы и большое сообщество. Но с типизацией и внедрением в готовый проект все очень туго. Как минимум потому, что тс не умеет выводить типы чистого жс, на основе использования кусков кода.
В этом плане флоу выигрывает. Его легко внедрить, он имеет минимум сверхъестественного синтаксиса, ну и с реактом все отлично.
Но сразу оговорюсь, с недавних пор я не большой приверженец типизации в жс. Конечн, она даёт некоторые гарантии, но также добавляет боль. Хотя по сути это просто проверки кода, его правильность, а также защиту от any, никто не гарантирует.
Но находятся люди, которые считают, что использование типизации, а особенно тс, позволяет им не тестировать свой код. Тут сложно что-то сказать, я все таки не психиатр.
Безумное желание все типизировать, похоже на попытку заняться сексом через матрас, ради безопасности.
Многие считают, что typescript это спасение всех жсеров от ошибок, но любой умный человек, пишущий на флоу, понимает, что дело совсем не в типизации. Дело в мемкрософт.
На деле же, с тс немного проще начать писать новый проект (не на реакте конечно). В тс хорошие тулзы и большое сообщество. Но с типизацией и внедрением в готовый проект все очень туго. Как минимум потому, что тс не умеет выводить типы чистого жс, на основе использования кусков кода.
В этом плане флоу выигрывает. Его легко внедрить, он имеет минимум сверхъестественного синтаксиса, ну и с реактом все отлично.
Но сразу оговорюсь, с недавних пор я не большой приверженец типизации в жс. Конечн, она даёт некоторые гарантии, но также добавляет боль. Хотя по сути это просто проверки кода, его правильность, а также защиту от any, никто не гарантирует.
Но находятся люди, которые считают, что использование типизации, а особенно тс, позволяет им не тестировать свой код. Тут сложно что-то сказать, я все таки не психиатр.
Безумное желание все типизировать, похоже на попытку заняться сексом через матрас, ради безопасности.
Пару лет назад, я ради опыта начал писать opensource проект — клон Instagram. Потом разумеется забросил, так как появились важные несуществующие дела.
Примерно месяц назад (в начале февраля 2018) я перезапустил разработку: react, redux, styled-components, @AtomicDesign + деление по фичам. И у меня встал вопрос “на чем писать бæкенд?”. Казалось бы, написать на nodejs (koa / next) самый быстрый и простой вариант, но мне захотелось получить новый опыт. А так как я уже почти год пассивно изучаю Rust, то врядли представится лучший способ прокачаться.
В дальнейшем я планирую писать некоторые отчеты и размышления о разработке Instaclone, как фронтенда так и бæкенда. Ссылки ради ⭐️:
github.com/sergeysova/instaclone-backend.rs
github.com/sergeysova/instaclone
Примерно месяц назад (в начале февраля 2018) я перезапустил разработку: react, redux, styled-components, @AtomicDesign + деление по фичам. И у меня встал вопрос “на чем писать бæкенд?”. Казалось бы, написать на nodejs (koa / next) самый быстрый и простой вариант, но мне захотелось получить новый опыт. А так как я уже почти год пассивно изучаю Rust, то врядли представится лучший способ прокачаться.
В дальнейшем я планирую писать некоторые отчеты и размышления о разработке Instaclone, как фронтенда так и бæкенда. Ссылки ради ⭐️:
github.com/sergeysova/instaclone-backend.rs
github.com/sergeysova/instaclone
GitHub
GitHub - sergeysova/instaclone-backend.rs
Contribute to sergeysova/instaclone-backend.rs development by creating an account on GitHub.
Как же обстоят дела с веб-разработкой в расте?
Для начала стоит начать с сайта arewewebyet.org, он сможет ответить на вопросы о возможности переезда с Rails/Rjango/Flask на Rust, а также обозначить список более-менее рабочих библиотек и фреймворков.
Я спросил в чате @rustlang_ru какую библиотеку/фреймворк мне выбрать в качестве веб-сервера для своего проекта, в ответ получил много предложений, но настоятельно рекомендовали hyper.rs.
Что-ж, это низкоуровневая библиотека, не имеющая в комплекте роутинга, но с возможностью асинхронщины на futures. Результат моих попыток есть в https://github.com/sergeysova/instaclone-backend.rs/tree/feature/hyper. Я практически сразу уткнулся в необходимость написания своего роутера, так как хэндлить роуты вроде /users/:user_id библиотека не умеет. Такой подход мгновенно отбил у меня желание писать дальше.
Следующим кандидатом выступил фреймворк Fanta docs.rs/crate/fanta. Этот подход мне понравился сильно больше, так как имел в своем арсенале всё, что нужно для работы с базой и http-запросами. Fanta построена на совместной работе serde.rs для сериализации, tokio.rs для работы с сетью, diesel.rs для работы с базой. Мне показалось, что я сделал правильный выбор, но молодость фреймворка сказалась также очень быстро. Пришлось писать слишком много сервисного кода, и слишком мало бизнес-логики. Буквально дальше сгенеренного приложения не зашло. https://github.com/sergeysova/instaclone-backend.rs/tree/feature/fanta
После очередного холивара в чате Rust, я обратил внимание на rocket.rs, который до этого выкинул из поля зрения, по причине работе только на nightly версии rustc. В этот раз, я решил рассмотреть его поближе. И о чудо, оно заработало, очень просто и приятно. Весь бойлерплейтный код скрывается в макросах
Имеется валидация параметров, входных данных, параметров query, cookies прямо из коробки да по структурам раста, и для этого не нужно писать лишнего кода, просто указать аргументы функции. Меня всё это очень сильно подкупило. Весьма неплохие гайды и документация по API сделали своё дело, за пару дней я написал несложное приложение с двумя роутами, прикрутил базу PostgreSQL с помощью diesel.rs и впридачу получил красивый логгер для отладки. Ко всему прочему, rocket из коробки имеет гайд по настройке пула соединений с базой на основе r2d2 docs.rs/crate/r2d2 и это прекрасно.
Вердикт: продолжаю использовать rocket + diesel для своего pet-проекта.
Для начала стоит начать с сайта arewewebyet.org, он сможет ответить на вопросы о возможности переезда с Rails/Rjango/Flask на Rust, а также обозначить список более-менее рабочих библиотек и фреймворков.
Я спросил в чате @rustlang_ru какую библиотеку/фреймворк мне выбрать в качестве веб-сервера для своего проекта, в ответ получил много предложений, но настоятельно рекомендовали hyper.rs.
Что-ж, это низкоуровневая библиотека, не имеющая в комплекте роутинга, но с возможностью асинхронщины на futures. Результат моих попыток есть в https://github.com/sergeysova/instaclone-backend.rs/tree/feature/hyper. Я практически сразу уткнулся в необходимость написания своего роутера, так как хэндлить роуты вроде /users/:user_id библиотека не умеет. Такой подход мгновенно отбил у меня желание писать дальше.
Следующим кандидатом выступил фреймворк Fanta docs.rs/crate/fanta. Этот подход мне понравился сильно больше, так как имел в своем арсенале всё, что нужно для работы с базой и http-запросами. Fanta построена на совместной работе serde.rs для сериализации, tokio.rs для работы с сетью, diesel.rs для работы с базой. Мне показалось, что я сделал правильный выбор, но молодость фреймворка сказалась также очень быстро. Пришлось писать слишком много сервисного кода, и слишком мало бизнес-логики. Буквально дальше сгенеренного приложения не зашло. https://github.com/sergeysova/instaclone-backend.rs/tree/feature/fanta
После очередного холивара в чате Rust, я обратил внимание на rocket.rs, который до этого выкинул из поля зрения, по причине работе только на nightly версии rustc. В этот раз, я решил рассмотреть его поближе. И о чудо, оно заработало, очень просто и приятно. Весь бойлерплейтный код скрывается в макросах
#[get(“/users/<user_id>”)]Имеется валидация параметров, входных данных, параметров query, cookies прямо из коробки да по структурам раста, и для этого не нужно писать лишнего кода, просто указать аргументы функции. Меня всё это очень сильно подкупило. Весьма неплохие гайды и документация по API сделали своё дело, за пару дней я написал несложное приложение с двумя роутами, прикрутил базу PostgreSQL с помощью diesel.rs и впридачу получил красивый логгер для отладки. Ко всему прочему, rocket из коробки имеет гайд по настройке пула соединений с базой на основе r2d2 docs.rs/crate/r2d2 и это прекрасно.
Вердикт: продолжаю использовать rocket + diesel для своего pet-проекта.
На счёт JWT небольшой текст.
Вижу смысл юзать его только для общения между серверами в неких опасных условиях.
Но почему оно того не стоит, можно прочесть по ссылке https://t.iss.one/why_jwt_is_bad
Вижу смысл юзать его только для общения между серверами в неких опасных условиях.
Но почему оно того не стоит, можно прочесть по ссылке https://t.iss.one/why_jwt_is_bad
Я слез с Rocket, когда не получилось написать трейт/структуру для указания аутентификации для роута.
Рокет позволяет с помощью макроса на хендлере роута указать миддлвары. О request guards можно почитать здесь.
Приблизительно, как это работает, макрос создает функцию которая будет вызываться каждый раз при запросе в указанный роут. В этой функции генерируется весь обслуживающий код, в том числе специальный вызов написанного хендлера с параметрами. Но так как Rust позволяет обратиться к дженерик типу (`T::some_method()`), перед вызовом хендлера, вызывает методы у типов его аргументов (`AuthOptional::from_request(&req)`).
Я хотел указывать там аутентификаци: опциональную или требуемую.
Опциональная: хендлер сам решает, что ему делать в случае отсутствия аутентификации. Чуть ли не через простой
Требуемая: миддлвара пропускает в хендлер только аутентифицированные запросы и кладет куда-то инстанс юзера, для удобства. Анонимам делает отлуп с
В nodejs это решается просто и удобно:
Всё было хорошо до момента, когда мне понадобилось из такой миддлвары вернуть кастомную ошибку и обработать ее для всех роутов. Пообщавшись с автором, оказалось, что такой функциональности тупо нет. Может быть сейчас уже добавили или я тогда не так изъяснялся, не знаю. Но мне не сильно вкатила идея макросов для роутов, так как это жесткое прибивание гвоздями пути роутера к хендлеру.
Рокет позволяет с помощью макроса на хендлере роута указать миддлвары. О request guards можно почитать здесь.
#[post("/search")]
fn search_handler(auth: AuthOptional) -> ... { ... }Приблизительно, как это работает, макрос создает функцию которая будет вызываться каждый раз при запросе в указанный роут. В этой функции генерируется весь обслуживающий код, в том числе специальный вызов написанного хендлера с параметрами. Но так как Rust позволяет обратиться к дженерик типу (`T::some_method()`), перед вызовом хендлера, вызывает методы у типов его аргументов (`AuthOptional::from_request(&req)`).
Я хотел указывать там аутентификаци: опциональную или требуемую.
Опциональная: хендлер сам решает, что ему делать в случае отсутствия аутентификации. Чуть ли не через простой
if session.is_auth().Требуемая: миддлвара пропускает в хендлер только аутентифицированные запросы и кладет куда-то инстанс юзера, для удобства. Анонимам делает отлуп с
401 и для этого не надо писать лишнего кода.В nodejs это решается просто и удобно:
router.post('/search', authOptional(), searchHandler)
router.post('/search/private', authRequired(), searchPrivateHandler)Всё было хорошо до момента, когда мне понадобилось из такой миддлвары вернуть кастомную ошибку и обработать ее для всех роутов. Пообщавшись с автором, оказалось, что такой функциональности тупо нет. Может быть сейчас уже добавили или я тогда не так изъяснялся, не знаю. Но мне не сильно вкатила идея макросов для роутов, так как это жесткое прибивание гвоздями пути роутера к хендлеру.
Итак actix.
Сам actix — фреймворк построенный на модели акторов. Я не вникал в эту модель и паттерны, перед тем, как начать писать на actix-web.
Actix по другому строит роутинг. Более привычным способом для разработчиков nodejs 😄.
Сами хендлеры не заворачиваются в макросы и остаются обычными функциями от аргументов. Но большинство хендлеров имеют тип
Но на самом деле, хендлер это тоже трейт —
Итак, что это даёт? Actix также как и Rocket умеет принимать хендлеры с кастомными аргументами.
Типичный хендлер выглядит так.
Но количество аргументов можно расширить через кортеж.
С таким подходом, реализовать отлуп required аутентификации становится в разы проще. Я написал две простеньких структуры
Ссылка на код в howtocards
Пример использования
Я не очень внимательно читал документацию по экстракторам и долго пытался понять как мне реализовать эту фичу. Пришлось связаться с автором actix и выяснить тонкости. Изначально, я хотел реализовать свой
Посмотреть примеры работы с actix можно посмотреть в репозитории sentry в директории server.
Также интересные подходы в написании веб-сервера есть в исходниках crates.io.
Сам actix — фреймворк построенный на модели акторов. Я не вникал в эту модель и паттерны, перед тем, как начать писать на actix-web.
Actix по другому строит роутинг. Более привычным способом для разработчиков nodejs 😄.
app.resource("/account", |route| {
route.method(Method::POST).with(account_handler)
});Сами хендлеры не заворачиваются в макросы и остаются обычными функциями от аргументов. Но большинство хендлеров имеют тип
Fn(..) -> impl Responder, это значит, что функция должна вернуть любой тип имплементирующий трейт Responder. Разработчики actix-web реализовали этот трейт для всех стандартных типов.Но на самом деле, хендлер это тоже трейт —
Handler (ссылка). В этом файле есть имплементация Handler для функции.Итак, что это даёт? Actix также как и Rocket умеет принимать хендлеры с кастомными аргументами.
Типичный хендлер выглядит так.
fn common_handler(req: HttpRequest<State>) -> impl Responder { ... }Но количество аргументов можно расширить через кортеж.
fn custom((req, auth, query): (HttpRequest<State>, Auth, Query<Info>)) -> impl Responder { ... }Auth, Query<T> называются Extractors и их задача вытаскивать что-то из запроса в хендлер, тоже своеобразный middleware. Хотя actix имеет полноценные middlewares, экстракторы очень полезны, так как позволяют делать асинхронные экстракторы и выполнять отлуп запроса, до исполнения хендлера.С таким подходом, реализовать отлуп required аутентификации становится в разы проще. Я написал две простеньких структуры
Auth и AuthOptional. Обе реализуют трейт FromRequest<State>.Auth делает отлуп запроса, если пользователь пришел без аутентификации или с дохлым токеном (и т.д.). AuthOptional просто дергает метод Auth::from_request но не делает отлуп пользователю, а заворачивает сессию в Option.Ссылка на код в howtocards
Пример использования
Я не очень внимательно читал документацию по экстракторам и долго пытался понять как мне реализовать эту фичу. Пришлось связаться с автором actix и выяснить тонкости. Изначально, я хотел реализовать свой
SessionBackend и пытаться крутиться вокруг него.Посмотреть примеры работы с actix можно посмотреть в репозитории sentry в директории server.
Также интересные подходы в написании веб-сервера есть в исходниках crates.io.
Сова пишет… via @like
Почему директории utils и helpers это свалка?
Начнем с того, как они появляются. Во время разработки проекта, программист старается выносить повторяющиеся куски кода в функции и переиспользовать их. В какой-то момент, в двух разных модулях требуется одна и та же функция, неопытный разработчик решает вынести функцию в отдельный модуль. Но почему-то останавливается на этом решении, создавая директорию/модуль utils или helpers, не думая о будущем этой части программы.
С ростом проекта, количество функций в этой директории растет. Также растет и количество разработчиков в проекте. Функций появляется все больше и больше. Зачастую никто не следит за структурой этих модулей и вполне возможно появление дублирования кода.
Как это решить?
Забудьте о директориях utils и helpers. Эти названия никак не доносят суть содержимого. А из правил чистого кода мы помним, название должно быть однозначным и отражать назначение.
Следует задуматься, почему вообще появилась необходимость в вынесении функции?
Почему они используются в таких разных частях проекта?
Возможно, ответом будет плохая организация кода всего проекта. Если хорошо поисследовать проект можно найти много кода, который достоин вынесения в отдельную библиотеку.
Если же этот код нельзя или не нужно выносить в полноценную библиотеку, его можно вынести в библиотеку внутри проекта. В случае JS, это можно сделать, создав полноценную библиотку внутри lib/.
Такой библиотеке нужно дать осмысленное однозначное название, написать документацию и тесты. Причем собрать в этой библиотеке весь связанный код. Например, вынести все функции работающие с датами во внутреннюю библиотеку lib/datetime. Префикс lib/ позволит избежать конфликтов имен, а также можно будет использовать простые и понятные имена. Конечно же, можно сделать npm scope, чтобы упростить будущую публикацию в npm. Например, @lib/datetime.
Чем это отличается от lib и helpers?
- весь код, выносится в полноценную библиотку с осмысленным названием, документацией и тестами
- lib явно описывает содержимое: это библиотека
- рефакторинг, публикация или удаление этой библиотеки становятся тривиальными задачами
Начнем с того, как они появляются. Во время разработки проекта, программист старается выносить повторяющиеся куски кода в функции и переиспользовать их. В какой-то момент, в двух разных модулях требуется одна и та же функция, неопытный разработчик решает вынести функцию в отдельный модуль. Но почему-то останавливается на этом решении, создавая директорию/модуль utils или helpers, не думая о будущем этой части программы.
С ростом проекта, количество функций в этой директории растет. Также растет и количество разработчиков в проекте. Функций появляется все больше и больше. Зачастую никто не следит за структурой этих модулей и вполне возможно появление дублирования кода.
Как это решить?
Забудьте о директориях utils и helpers. Эти названия никак не доносят суть содержимого. А из правил чистого кода мы помним, название должно быть однозначным и отражать назначение.
Следует задуматься, почему вообще появилась необходимость в вынесении функции?
Почему они используются в таких разных частях проекта?
Возможно, ответом будет плохая организация кода всего проекта. Если хорошо поисследовать проект можно найти много кода, который достоин вынесения в отдельную библиотеку.
Если же этот код нельзя или не нужно выносить в полноценную библиотеку, его можно вынести в библиотеку внутри проекта. В случае JS, это можно сделать, создав полноценную библиотку внутри lib/.
Такой библиотеке нужно дать осмысленное однозначное название, написать документацию и тесты. Причем собрать в этой библиотеке весь связанный код. Например, вынести все функции работающие с датами во внутреннюю библиотеку lib/datetime. Префикс lib/ позволит избежать конфликтов имен, а также можно будет использовать простые и понятные имена. Конечно же, можно сделать npm scope, чтобы упростить будущую публикацию в npm. Например, @lib/datetime.
Чем это отличается от lib и helpers?
- весь код, выносится в полноценную библиотку с осмысленным названием, документацией и тестами
- lib явно описывает содержимое: это библиотека
- рефакторинг, публикация или удаление этой библиотеки становятся тривиальными задачами
Не так давно в чатах обсуждали (снова) чем отличается фреймворк от библиотеки.
https://dev.to/ben/whats-the-difference-between-a-library-and-a-framework-3blo
В двух словах:
- В случае фреймворка, вы встраиваете свой код в его архитектуру
- Но библиотеку вы самостоятельно встраиваете в собственную архитектуру
https://dev.to/ben/whats-the-difference-between-a-library-and-a-framework-3blo
В двух словах:
- В случае фреймворка, вы встраиваете свой код в его архитектуру
- Но библиотеку вы самостоятельно встраиваете в собственную архитектуру
DEV Community
What's the difference between a library and a framework?
Having a look at this comment by @kayis from another thread, I'm wondering if you agree with this st...
Наконец-то, хоть кто-то написал почему снапшот тесты компонентов бесполезны. Хотел уже давно описать, но руки перегорели.
https://foobarbaz.club/why-i-stopped-using-snapshot-testing-with-jest/
https://foobarbaz.club/why-i-stopped-using-snapshot-testing-with-jest/
Forwarded from 🦉
Ребята, вы давно просили видео с презентации React SPB Meetup об atomic design и feature slices, но нам запороли запись.
Поэтому я вынес ключевые слайды с комментариями в отдельный канал.
https://t.iss.one/joinchat/AAAAAFcbHfDlRV0eK8kt8w
Поэтому я вынес ключевые слайды с комментариями в отдельный канал.
https://t.iss.one/joinchat/AAAAAFcbHfDlRV0eK8kt8w
Сова пишет… via @like
У меня каждая директория описывает либо одну сущность, либо их набор.
с файлами похожая штука
Вложение директорий определяется вложением сущностей.
— как понять, что есть сущность, а что нет?
— нужно определиться, можно ли с “этим” работать не погружаясь в детали. Можно ли к “этому” обращаться как единой цельной структуре?
страница регистрации сущность? Мы можем ее заимпортить как цельную сущность — да. Можем изменить именно эту страницу — да. Страница цельная сама по себе — да.
ui — сущность? мы можем заимпортить ui и работать с ним в коде — да. Можно ли к нему обращатсья как к цельной структуре — нет(он не несет в себе функциональности, только его части по отдельности ее имеют).
features/ — набор сущностейfeatures/name — одна сущность./pages/ — набор сущностейс файлами похожая штука
./reducer.js — одна сущность./actions.js — набор сущностейВложение директорий определяется вложением сущностей.
— как понять, что есть сущность, а что нет?
— нужно определиться, можно ли с “этим” работать не погружаясь в детали. Можно ли к “этому” обращаться как единой цельной структуре?
страница регистрации сущность? Мы можем ее заимпортить как цельную сущность — да. Можем изменить именно эту страницу — да. Страница цельная сама по себе — да.
ui — сущность? мы можем заимпортить ui и работать с ним в коде — да. Можно ли к нему обращатсья как к цельной структуре — нет(он не несет в себе функциональности, только его части по отдельности ее имеют).
Тем временем, я ухожу из коммерческой разработки на JavaScript.
Возможно, здесь будет больше постов о js и rust
Возможно, здесь будет больше постов о js и rust
@artalar подкинул статью: https://daneden.me/2018/01/05/subatomic-design-systems/
На первый взгляд выглядит проще Atomic Design, но имеет больше математических концепций.
На первый взгляд выглядит проще Atomic Design, но имеет больше математических концепций.
@sredov раздобыл такой подход: https://medium.com/ge-design/ges-predix-design-system-8236d47b0891
В его основе лежит @AtomicDesign
В его основе лежит @AtomicDesign
Medium
GE’s Predix Design System
Scaling Atomic Design for the Enterprise
Нашел очередной бандлер пакетов.
Эта штука позволит собрать почти любой package: javascript, typescript, reasonml, wasm и в несколько таргетов node, web, bin.
pika имеет минималистичный API и расширяемую систему плагинов.
Возможно, это сможет ускорить разработку библиотек. Сомнительно, что его можно использовать для сборки целых проектов.
https://github.com/pikapkg/pack
Эта штука позволит собрать почти любой package: javascript, typescript, reasonml, wasm и в несколько таргетов node, web, bin.
pika имеет минималистичный API и расширяемую систему плагинов.
Возможно, это сможет ускорить разработку библиотек. Сомнительно, что его можно использовать для сборки целых проектов.
https://github.com/pikapkg/pack
GitHub
GitHub - FredKSchott/pika-pack: 📦⚡️ Build your npm package using composable plugins. https://www.pika.dev/blog/introducing-pika…
📦⚡️ Build your npm package using composable plugins. https://www.pika.dev/blog/introducing-pika-pack/ - GitHub - FredKSchott/pika-pack: 📦⚡️ Build your npm package using composable plugins. https://...
Сова пишет… via @like
Пишу на жс 5+ лет. Из них писал 3 года на типизированном.
За это время успел полюбить и возненавидеть типизацию. В итоге сделал вывод, что типизация в жс, только замедляет разработку.
Потому что приходится тратить время на борьбу с тайпчекером, даже там, где по опыту знаешь, что всё збс будет работать.
А с тс вообще нельзя быть уверенным, что если тайпчек прошел, всё будет работать. Всё равно запускаешь код и проверяешь, что всё ок. Плюсы от тс во время разработки меркнут по сравнению с минусами.
Но типизация помогает в рефакторинге. Идешки подсказывают по методам достаточно хорошо. Но тут, что флоу, что тс, вполне хорошо справляются.
Но когда знакомишься с языком с настоящей типизацией, то писать на тс становится невозможно. На флоу ещё более менее, потому что там только хинты типов, не более. А тс вроде как язык, но мало того, что обманывает с типами, так ещё и никаких фич работы с типами не предоставляет.
Так что тс отправляется в мусорку. Флоу может быть и можно использовать. Из перспективных типизаций вижу только полноценные языки поверх жс: elm, reason, или ещё что.
За это время успел полюбить и возненавидеть типизацию. В итоге сделал вывод, что типизация в жс, только замедляет разработку.
Потому что приходится тратить время на борьбу с тайпчекером, даже там, где по опыту знаешь, что всё збс будет работать.
А с тс вообще нельзя быть уверенным, что если тайпчек прошел, всё будет работать. Всё равно запускаешь код и проверяешь, что всё ок. Плюсы от тс во время разработки меркнут по сравнению с минусами.
Но типизация помогает в рефакторинге. Идешки подсказывают по методам достаточно хорошо. Но тут, что флоу, что тс, вполне хорошо справляются.
Но когда знакомишься с языком с настоящей типизацией, то писать на тс становится невозможно. На флоу ещё более менее, потому что там только хинты типов, не более. А тс вроде как язык, но мало того, что обманывает с типами, так ещё и никаких фич работы с типами не предоставляет.
Так что тс отправляется в мусорку. Флоу может быть и можно использовать. Из перспективных типизаций вижу только полноценные языки поверх жс: elm, reason, или ещё что.