Обновить
1
Дмитрий@ReturnVoid

Frontend Developer

Отправить сообщение

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

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

Спасибо за статью 👍

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

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

Важное напоминание, спасибо за статью.

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

Есть маленькие библиотеки, которые исправляют эти косяки, например ts-reset, с ними жить становится чуть безопаснее.

А часом не пробовали вот эту либу? Очень похожа на то что вы описали.

Уже давно пришел к выводу что типы тестировать в любом случае придётся в большом проекте или просто библиотеке, поэтому никаких вопросов нет, думаю как упростить внедрение этого процесса в рутину команды.

Думаю копать в сторону настроек компилятора чтобы тесты типов можно было прогонять отдельно, но чтобы это не мешало сборки проекта в целом (нужно для гибкости ci/cd)

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

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

А уж к какому коду в итоге вас приведет такой подход зависит от ваших предпочтений и задач.

Вы можете попробовать удалить какие-то фрагменты и посмотреть к каким результатам это приведет.

Мне показалось, что изначальная мысль: "Как заставить TS работать на вас" - недостаточно тесно связана со следующими вещами:

  1. Нужно проектировать больше

  2. Нужно знать и учитывать о js больше

  3. Нужно знать и учитывать особенностей о ts больше

Это тема для другой статьи 😉

Как вы это учли при написании реализации?

Вы использовали: value.match(/^(\d+)([a-zA-Z%]*)$/)

Хотя, если посмотреть на тип там нет [a-zA-Z].

Очень просто - никак.

Так как это не является существенной проблемой, ввиду строгих типов в любом случае не получится пропихнуть туда что-то нелегальное (если сильно не стараться, конечно 🤫).

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

Благодарю за обратную связь.

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

Статья стремится показать как можно путем использования особенностей TS получать помощь в написании и проектировании кода со стороны IDE отдав ей часть мыслительной нагрузки.

В конце вы сами выводите эту мысль

Действительно, когда создаём программы на js и ts, по-разному относимся к проектированию. TS требует, чтобы проектированию изначально уделялось больше внимания. Типы — это именно про то, чтобы в коде дизайн был ярко выраженным. Когда вы выбираете тип, вы в первую очередь думаете о дизайне программы, а не просто о том, чтобы это всё завелось, когда банально партируете js на ts. И вот когда вы изначально ставите себе ясную задачу и объясняете себе её детали, типы начинают работать.

Мне даже захотелось ее скопировать в выводы, очень хорошо отражает то что хотелось донести 😉

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

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

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

Более строгая типизация в TS может быть достигнута через классы, обратите внимание как устроен NestJS (фреймворк для бэкенда).

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

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

Пустой массив возвращается из match так как match может вернуть null, тип null исключается путем добавления заглушки в виде пустого массива чтобы не писать в дальнейшем проверку на null. Это просто предпочтение, не ищите глубоких смыслов.

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

Ширина ладно. В реальности там намного больше возможных единиц, но их нетрудно перечислить. Опустим сейчас всякие auto и max-content, хотя с ними есть вопросы.

Конечно, в реальном коде вариативность может быть существенно больше (или меньше), но для демонстрации механики достаточно, что типов просто больше чем один.

А вот допустим в CSS есть несколько форматов цветов, у каждого по нескольку вариаций форматов параметров и корректно их все учесть - задачка нетривиальная.Тоже предлагаете всё типизировать?

Нет, с чего вы взяли? Не все строки необходимо типизировать, некоторые действительно стоит оставить просто строками без дополнительных деталей как в примере что вы привели.

А если кто-то передал некорректную CSS-строчку, то сам себе буратино.

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

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


Не угадать с типами действительно можно - это, конечно, вопрос к постановщику задачи, но не будем о грустном 🥲

Однако, даже в такой ситуации можно достаточно легко расширять типы.

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

К сожалению, на словах это сложно принять, поэтому я настоятельно рекомендую вам именно попробовать написать что-то в таком стиле чтобы почувствовать, так сказать, на кончиках пальцев 😉

Подобный пример служит для демонстрации крайне малозаметной ошибки. Вероятность такой ошибки не имеет значения для учебного примера.

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

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

Информация

В рейтинге
Не участвует
Откуда
Санкт-Петербург, Санкт-Петербург и область, Россия
Дата рождения
Зарегистрирован
Активность

Специализация

Фронтенд разработчик
Старший
TypeScript
JavaScript
Vue.js
Angular
NestJS
Веб-разработка