Как стать автором
Обновить

Комментарии 5

Были ли какие-то плюсы или минусы от смены собственно типизации? Например, некоторые типы стали точнее или описываются короче, или наоборот? Удалось ли отловить какие-то баги за счет именно TS? Изменилось ли время сборки, и еcли да, то как?

Благодарю за вопрос.

Были ли какие-то плюсы или минусы от смены собственно типизации?

Плюсы однозначно были и есть.

Во flow, например, есть разница между записью типов type A = {val: string} и type A = {| val: string |}. Когда как в TS такого разночтения смыслов нет.
Мое любимое - type A = { val?: ?string }, что означает по сути val: string | undefined | null. В TS это выглядит более привычно и наглядней val?: string | null. Точно ясно, что Flow.js по сравнению с TS в некоторых местах очень похож, но между тем имеет немного другую семантику. Оно и понятно, ведь разрабатывались они в разное время. TS на мой взгляд более лаконичен, использует меньше разного рода специальных символов внутри своей записи, тебе не нужно писать фигурные и угловые скобки только потому, что такой синтаксис. Есть ли минусы от перехода с flow на TS - я лично не заметил. Стало меньше конфигов, банально меньше символов на запись того же самого, меньше аннотаций.
Например Flow.js запись

onClick: $PropertyType<ComponentProps, 'onClick'>,

становится более понятно, читабельной, короче в записи

onClick: ComponentProps['onClick']

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

Например, некоторые типы стали точнее или описываются короче, или наоборот?

Однозначно типы стали записываться короче и точней хотя бы потому, что вывод типов в TS работает на порядок лучше чем во Flow. И уже на стадии разработки можно видеть что будет в той или иной переменной. Тут сильно помогает интеграция TS со студией разработки. Но надо заметить, что Flow.js также поддерживается, однако это не мешало время от времени проскакивать ошибкам.

Удалось ли отловить какие-то баги за счет именно TS?

Было несколько багов связанных именно с типизацией.

Например, только после переписывания типа на TS  с сохранением всех полей этого типа, мы увидели ошибку в данных, что в компонент на самом деле на вход требовались другие данные, а часть вообще была лишней. Статический анализатор flow этого не замечал. В компонент можно было прописать любое количество полей, даже если они не нужны, как если бы был просто тип any. А вот TS уже не позволяет таких косяков, и это здорово.

Изменилось ли время сборки, и если да, то как?

Я бы не сказал, что в этом месте что-то драматически изменилось.  По ощущениям компилятор TS во время прогона линтера стал немного быстрей и, что самое классное, более точно показывает место ошибок, чем во flowjs, который просто намекал, что типы “тут” не совпадают с тем, что указано “там“.

Спасибо, исчерпывающий ответ!

По какому принципу договорились хранить типы в проекте? Конкретно, где, в скольких файлах, по типу на файл или группировка по какому либо признаку?

Это отличный и практичный вопрос.


В проекте можно выделить несколько явных категорий типов:

  • Тайпинги из импортируемой библиотеки компонентов

    • Они пришли вместе с пакетом, специально мы их не обрабатывали

  • Импортируемые компоненты, которые написаны на JS и не имели своих тайпингов.

    • Для них мы завели свои тайпинги в отдельном глобальном на проект файле через declare type SomeType = 'string' и declare global { } там, где типы имели импорты.

  • Наши собственные типы, которые являются, как говорится, common для всего проекта.

    • Вынесли в отдельную директорию “на верх” проекта. Тут и декларации, и просто export type

  • Типы в самих компонентах по месту использования. Тут два основных способа.

    • Если для компонента нужно иметь множество типов, больше 1-2-ух, то они выносятся в отдельный файл в директории компонента. Например, тип используется и в файле-контейнере, и в файле-компоненте.

    • Если типов всего 1-2, то они декларируются по месту использования, то есть в том компоненте, где это нужно.

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

Мне довелось поработать в таким подходом, когда все типы раскладывались по папкам с типами где-то отдельно. И когда типы клались по месту использования.
Оба подхода в какой-то мере имеют смысл, имеют свои плюсы и минусы, имеют право на жизнь. Тут скорее вопрос удобства работы. Подход с типами "по месту" мне нравится.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий