Пока что единственным инструментом который "продал" мне инъекцию зависимостей в жс стал effect. Почти все подобные инструменты пытались навязать мне запихивание любой сущности в класс и обмазывание декораторами, никогда не понимал почему кто-то считает что это удобно. Не говоря уже о том что никакой статической гарантии того что ты правильно построил зависимости не будет скорее всего, за этим сам следи. Эффект в сравнении со всем этим кажется таким простым и понятным.
Жалко что не написали как gitops делается на vps. По факту это настолько просто что целый специальный хостинг без надобности. Достаточно вместо того чтобы делать docker compose up напрямую на сервере создать удалённый контекст:
docker context create vps --docker "host=ssh://me@example.com"
docker context use vps
И можно деплоить на vps из того же github workflow.
Проверка на лишние свойства не работает везде потому что не должна. Система типов нечего против лишних свойств не имеет, они всегда допустимы. Проверка на лишние свойства существует в тех местах где по мнению разработчиков они провоцируют баги, не смотря на то что типы верны. Это как жаловаться что правила линтера можно обойти.
Лазерная коррекция не единственная. Есть например имплантация факичных линз, о которой в рунете почему-то мало говорят, хотя у нас такие операции тоже вполне себе делают. В отличии от лазерной коррекции имплантированные линзы можно извлечь/поменять при возникновении осложнений или ухудшении зрения.
Не очень понял тогда в чём здесь недостаток именно тс. Если в дто есть пароль, а его там при этом быть не должно, это просто ошибка дизайна дто. На любом языке так будет.
Не понятно в чем проблема в данном случае. Если в том что пароль приходит на фронт то система очевидно дырявая уже на беке который этот пароль отправил, тут тс не виноват. Если в том что это где-то помешает функционировать программе то это достаточно редкий случай, всё-таки стоит на тс писать с учётом того что в объекте может лежать что угодно ещё кроме того что позволяет тип, но в целом это конечно недостаток.
Готовить это проще всего в описанном случае через code first автогенерацию клиента апи на фронте из кода на беке, тогда такие случаи будут исключены. Или делать design first чтобы было больше возможности подумать над тем что отправляете.
Да я собственно не рекомендовал тут ничего и не навязывал, не поймите неправильно. Просто спросил почему было сделано именно так и привёл пару примеров.
Что касается моего личного мнения, я не люблю использовать классы как пространства имён потому что это добавляет когнитивной сложности коду. Когда я вижу слово class я ожидаю увидеть там класс, а не пространство имён. По этой же логике например предпочитаю function declaration вместо стрелок. Но эту вкусовщину я не навязываю никому.
От части да, но на самом деле я не особо понимаю претензий к тому что ЯП неудобен "без иде". С таким же успехом можно говорить что он неудобен на бумаге или на глиняной табличке. Не считаю это недостатком, так как не пользуюсь ни табличками, ни блокнотом.
Мне кажется что делать языки которые полагаются на мощности внешних инструментов вроде иде и языковых серверов это нормально. В современных реалиях я бы в принципе не стал пользоваться языком, у которого нет такой поддержки. Как бы он не был хорош он будет проигрывать в продуктивности разработки тем языкам, у которых такая поддержка есть.
Полагаться на иде так же нормально, как полагаться на компилятор.
На самом деле, не смотря на то, что статья явно байт, я полностью согласен с тезисами про многословность и неповоротливость статической типизации (в мейнстримных языках).
Особенно вот с этим:
let total: f64 = price.parse::<f64>().unwrap() * quantity.parse::<f64>().unwrap();
Примерно поэтому раст для меня совершенно невыносим.
Однако, в общем случае я не согласен разменивать гарантии от компилятора на гибкость и выразительность, я правда полагаюсь на эти ошибки и они часто выручают меня. Не говоря уже о том, что дело не только в ошибках. Почти весь современных developer experience вроде автодополнения и подсказок невозможен без тщательного анализа программ, которому крайне плохо поддаются динамически типизированные языки. Одно только отсутствие интеллисенса является поводом не писать на очередном perl или lua вообще. Это огромный удар по моей продуктивности как разработчика.
Но самое грустное в этой истории, пожалуй, не то, что придётся в очередной раз писать на очередной джаве или расте. Грустно что на самом деле теория языков программирования уже давно решила большинство проблем, обозначенных в статье. И решила она их не вчера, а десятки лет назад. Но мейнстримые языки программирования в упор не хотят замечать эти разработки.
Подобные поиски действительно удобного языка программирования привели меня к ML (Meta Language, а не Machine Learning) и его современным диалектам вроде OCaml и F#. Я до сих пор считаю что, за мелкими исключениями, это идеальный язык программирования.
Вот, взгляните:
let add a b = a + b
Никаких типов не указано, всё максимально просто и понятно (за исключением непривычного для мейнстрима синтаксиса). При этом типы существуют и полностью выводятся автоматически.
При этом в ML не нужно никаких IO монадов. Хочешь писать императивно с изменяемыми переменными и циклами? Так и пишешь:
let count n =
let i = ref 0 in
while !i < n do
Printf.printf "%d\n" !i;
i := !i + 1
done
И всё ещё никаких явных типов. И всё ещё гарантия безопасности и нормальный DX. Невероятно жаль что подобные вещи не ушли в мейнстрим.
На этом историю можно было бы закончить, но в TypeScript тело функции предиката типов не проверяется на фактическую корректность в отношении анализа переданного значения.
const isNumber1: (x: unknown) => x is number = (x) => { // Error
return true
}
const isNumber2: (x: unknown) => x is number = (x) => { // Ok
return typeof x === "number"
}
Статья как будто бы обо всём и ни о чём при этом. Вместо вольного пересказа документации можно было просто ссылки на неё дать, там изложение вполне доступное и корректное.
Касательно "нововведений":
Рассмотрим несколько ключевых новшеств, появившихся в последних версиях TS.
В каких версиях?
TypeScript теперь умеет оптимизировать условные типы глубже, избегая избыточных вычислений при работе с большими union-типами. Это ускоряет компиляцию и снижает нагрузку на систему типов.
Когда добавили? При чём тут Simplify? Сюда бы ссылку на блогпост или на пул реквест с пояснениями.
Ранее у TypeScript были ограничения на глубину рекурсии для условных типов. Теперь эти лимиты увеличены, что дает простор для еще более глубоких алгоритмов:
Когда раньше? Какие были ограничения? Какие стали? С чем это связано? Опять же, даже если не объяснять надо хотя бы ссылку на источник дать.
В общем случае для таких штук удобнее не юнион вообще всех ключей сразу собирать, а постепенно выдавать подсказки по уровням вложенности (как в иде). Это решает проблемы со слишком большими юнионами, вычисляемыми ключами и массивами.
Чтобы примерно так работало:
const data = { foo: { a: string, b: number }, bar: string }
validatePath(data, "")
// ^ 'foo' | 'bar'
validatePath(data, "foo.")
// ^ 'foo.a' | 'foo.b'
Пока что единственным инструментом который "продал" мне инъекцию зависимостей в жс стал effect. Почти все подобные инструменты пытались навязать мне запихивание любой сущности в класс и обмазывание декораторами, никогда не понимал почему кто-то считает что это удобно. Не говоря уже о том что никакой статической гарантии того что ты правильно построил зависимости не будет скорее всего, за этим сам следи. Эффект в сравнении со всем этим кажется таким простым и понятным.
Жалко что не написали как gitops делается на vps. По факту это настолько просто что целый специальный хостинг без надобности. Достаточно вместо того чтобы делать
docker compose up
напрямую на сервере создать удалённый контекст:И можно деплоить на vps из того же github workflow.
Проверка на лишние свойства не работает везде потому что не должна. Система типов нечего против лишних свойств не имеет, они всегда допустимы. Проверка на лишние свойства существует в тех местах где по мнению разработчиков они провоцируют баги, не смотря на то что типы верны. Это как жаловаться что правила линтера можно обойти.
А в чем противоречие? В фп кто-то мешает нормально именовать сущности? Не требует != противоречит же.
Лазерная коррекция не единственная. Есть например имплантация факичных линз, о которой в рунете почему-то мало говорят, хотя у нас такие операции тоже вполне себе делают. В отличии от лазерной коррекции имплантированные линзы можно извлечь/поменять при возникновении осложнений или ухудшении зрения.
Это легко решается включением подсказок
А чем это лучше старой доброй объектной алгебры?
Не очень понял тогда в чём здесь недостаток именно тс. Если в дто есть пароль, а его там при этом быть не должно, это просто ошибка дизайна дто. На любом языке так будет.
Не понятно в чем проблема в данном случае. Если в том что пароль приходит на фронт то система очевидно дырявая уже на беке который этот пароль отправил, тут тс не виноват. Если в том что это где-то помешает функционировать программе то это достаточно редкий случай, всё-таки стоит на тс писать с учётом того что в объекте может лежать что угодно ещё кроме того что позволяет тип, но в целом это конечно недостаток.
Готовить это проще всего в описанном случае через code first автогенерацию клиента апи на фронте из кода на беке, тогда такие случаи будут исключены. Или делать design first чтобы было больше возможности подумать над тем что отправляете.
Да я собственно не рекомендовал тут ничего и не навязывал, не поймите неправильно. Просто спросил почему было сделано именно так и привёл пару примеров.
Что касается моего личного мнения, я не люблю использовать классы как пространства имён потому что это добавляет когнитивной сложности коду. Когда я вижу слово
class
я ожидаю увидеть там класс, а не пространство имён. По этой же логике например предпочитаю function declaration вместо стрелок. Но эту вкусовщину я не навязываю никому.Неймспейсы предлагаются не как замена модулям, а как замена "статическим классам". В модулях. В этом плане они ни чуть не устарели.
Зачем в тс использовать "статические классы"? Просто интересно. Почему не модули или неймспейсы например?
Как же приятно видеть в статье источники, почаще бы так писали. А почему нету в хабе Typescript?
От части да, но на самом деле я не особо понимаю претензий к тому что ЯП неудобен "без иде". С таким же успехом можно говорить что он неудобен на бумаге или на глиняной табличке. Не считаю это недостатком, так как не пользуюсь ни табличками, ни блокнотом.
Мне кажется что делать языки которые полагаются на мощности внешних инструментов вроде иде и языковых серверов это нормально. В современных реалиях я бы в принципе не стал пользоваться языком, у которого нет такой поддержки. Как бы он не был хорош он будет проигрывать в продуктивности разработки тем языкам, у которых такая поддержка есть.
Полагаться на иде так же нормально, как полагаться на компилятор.
На самом деле, не смотря на то, что статья явно байт, я полностью согласен с тезисами про многословность и неповоротливость статической типизации (в мейнстримных языках).
Особенно вот с этим:
Примерно поэтому раст для меня совершенно невыносим.
Однако, в общем случае я не согласен разменивать гарантии от компилятора на гибкость и выразительность, я правда полагаюсь на эти ошибки и они часто выручают меня. Не говоря уже о том, что дело не только в ошибках. Почти весь современных developer experience вроде автодополнения и подсказок невозможен без тщательного анализа программ, которому крайне плохо поддаются динамически типизированные языки. Одно только отсутствие интеллисенса является поводом не писать на очередном perl или lua вообще. Это огромный удар по моей продуктивности как разработчика.
Но самое грустное в этой истории, пожалуй, не то, что придётся в очередной раз писать на очередной джаве или расте. Грустно что на самом деле теория языков программирования уже давно решила большинство проблем, обозначенных в статье. И решила она их не вчера, а десятки лет назад. Но мейнстримые языки программирования в упор не хотят замечать эти разработки.
Подобные поиски действительно удобного языка программирования привели меня к ML (Meta Language, а не Machine Learning) и его современным диалектам вроде OCaml и F#. Я до сих пор считаю что, за мелкими исключениями, это идеальный язык программирования.
Вот, взгляните:
Никаких типов не указано, всё максимально просто и понятно (за исключением непривычного для мейнстрима синтаксиса). При этом типы существуют и полностью выводятся автоматически.
При этом в ML не нужно никаких IO монадов. Хочешь писать императивно с изменяемыми переменными и циклами? Так и пишешь:
И всё ещё никаких явных типов. И всё ещё гарантия безопасности и нормальный DX. Невероятно жаль что подобные вещи не ушли в мейнстрим.
С недавних пор проверяется
Таких проектов на самом деле много и делают их давно. В известном бенчмарке почти все топовые решения примерно так и работают.
Статья как будто бы обо всём и ни о чём при этом. Вместо вольного пересказа документации можно было просто ссылки на неё дать, там изложение вполне доступное и корректное.
Касательно "нововведений":
В каких версиях?
Когда добавили? При чём тут
Simplify
? Сюда бы ссылку на блогпост или на пул реквест с пояснениями.Когда раньше? Какие были ограничения? Какие стали? С чем это связано? Опять же, даже если не объяснять надо хотя бы ссылку на источник дать.
Этому нововведению кстати уже 4 год пошёл.
А этому уже 5 год.
Пример тем временем не содержит
keyof
вообще. Я так и не понял о чём речь была.Чтобы не "взрывать компилятор" там просто стоит строгое ограничение на глубину рекурсии. Ничего задавать он не позволяет.
В примере просто какая-то счётная логика, это никак не "нововведение в TypeScript".
Можно например так сделать (не знаю насколько проще, но имхо понятнее):
В общем случае для таких штук удобнее не юнион вообще всех ключей сразу собирать, а постепенно выдавать подсказки по уровням вложенности (как в иде). Это решает проблемы со слишком большими юнионами, вычисляемыми ключами и массивами.
Чтобы примерно так работало: