🔥

Тред (Али Рагимов)


Как верно было замечено, TS из коробки не сильно отличается от JS. Это сделано для обратной совместимости - далеко не все проекты начинаются с нуля на TS Поэтому если в вашем проекте конфиг не тюнили, вы получаете лишь малую часть того, что даёт TS. Поговорим о «флагах строгости»

В официальной документации эти флаги раскиданы по секциям Strict Checks, Linter Checks и ещё немного в Advanced. С первыми двумя, на первый взгляд, всё понятно. А Advanced вызывает вопросы. Давайте разберёмся

Вот первая группа флагов – Strict Checks. Это самая понятная секция. По умолчанию все флаги выключены. Но в примере я демонстрирую максимально строгий режим gist.github.com/barinbritva/cf…
notion image

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

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

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

TS начинается с noImplicitAny: true Два слова про any. Это тип, который назначается всем переменным, если тип не был задан явно и не может быть выведен компилятором. С точки зрения TS, все переменные в JS это any, поскольку там нет системы типов
notion image

С переменной типа any можно делать что угодно, как мы привыкли это делать в JS. Но мы не для этого пишем на TS noImplicitAny всё ещё разрешает использовать any, но это нужно делать явно. Тем самым автор говорит: я понимаю, что делаю и беру риски на себя
notion image

Это стоит использовать лишь в крайнем случае, когда никак не получается определить или подружить типы TS код это когда noImplicitAny: true и руками мы тоже any нигде не пишем. Или почти нигде - будем реалистами 😉

В JS два нижних типа null и undefined В TS по умолчанию переменная любого типа может содержать значение null или undefined. Проверка переменных перед их использованием лежит на плечах программиста
notion image

Установив strictNullChecks: true мы предохраняем себя от подобных ситуаций С эти флагом мы должны явно разрешать переменным содержать null или undefined: let a: number | null | undefined
notion image

Установив strictFunctionTypes: true мы включаем более строгую проверку сигнатур функций
notion image

Вот теперь это больше похоже на TypeScript! Так сказать джентельменский набор TS разработчика Оставшиеся флаги, конечно тоже лучше включить. Если вдруг что-то пойдёт не так, можно выключить именно проблемный флаг до выяснения обстоятельств Про них буквально по паре слов:

strictPropertyInitialization - следит, чтобы свойства класса были проинициализированы. Дополнение к strictNullChecks, который должен быть тоже включен noImplicitThis - при использовании this проверяет, что контекст выполнения известен
notion image
notion image

strictBindCallApply - более строго проверят сигнатуры при использовании соответствующих методов: bind, call, apply
notion image

Подведём итоги секции Strict Checks: здесь действительно все флаги очень полезные. С ними TS раскрывает свой потенциал все флаги можно включить разом через strict: true как минимум следуют включить noImplicitAny, strictNullChecks и strictFunctionTypes

Следующая секция - Linter Checks. Название подразумевает, что это не про компиляцию, а качество кода. И эти проверки можно переложить на соответствующий инструмент - eslint. И это так, но лишь отчасти. Кажется, первые 2 флага находятся не на своих местах gist.github.com/barinbritva/cf…
notion image

В анонсах флагов noPropertyAccessFromIndexSignature и noUncheckedIndexedAccess было написано, что эти флаги не поместили под управление опцией strict, просто потому, что они на любителя Стало быть Linter Checks не место для этих флагов. Всё таки это про проверку типов

noPropertyAccessFromIndexSignature запрещает обращаться к свойствам объекта через точку, если свойства не объявлены в объекте явно, а например, через [key: string]: string devblogs.microsoft.com/typescript/ann…
notion image

Если мы объявляем переменную как let a: string[], то объекты, полученные по любым индексам a[0], a[1000] будут иметь тип string. На деле же это может быть undefined noUncheckedIndexedAccess будет заставлять проверять переменные перед использованием devblogs.microsoft.com/typescript/ann…
notion image

Оставшиеся же флаги можно легко заменить аналогичными правилами eslint noFallthroughCasesInSwitch - eslint.org/docs/rules/no-… noImplicitReturns -eslint.org/docs/rules/con… noUnusedLocals - eslint.org/docs/rules/no-… noUnusedParameters - eslint.org/docs/rules/no-…

Секция Advanced отличается от предыдущих тем, что содержит помимо флагов строгости множество других (их мы пропустим). И тем, что для строгости эти флаги должны быть установлены в ❗false❗ Мы рассмотрим только те, что касаются нашей темы gist.github.com/barinbritva/cf…
notion image

allowUnreachableCode разрешает недосягаемый код - код, написанный после операторов return, throw, break, continue allowUnusedLabels разрешает не используемые лэйблы. Так понимаю, конструкция, на которой наши далёкие предки писали циклы. Мы их вряд ли когда встретим

Мы запрещаем это поведение установкой false или настройкой eslint allowUnreachableCode - eslint.org/docs/rules/no-… allowUnusedLabels - eslint.org/docs/rules/no-… И переходим к завершающей фазе

С последними 4 флагами ничего не делаем - с ними всё хорошо. Скажу лишь, что noImplicitUseStrict это немного иначе работающий alwaysStrict - только он отменяет добавление "use strict" в некоторых случаях... Можно просто не думать о нём

А noStrictGenericChecks, suppressExcessPropertyErrors и suppressImplicitAnyIndexErrors запрещают практическое явное нарушение типизации. Временно устанавливать их в true можно лишь в крайних случаях - например портирование большого проекта с JS. В других случаях не стоит

Итак, вот наш итоговый, реорганизованный, самый строгий tsconfig! gist.github.com/barinbritva/cf…
notion image

Чтобы всё это добро не cмешивалось с другими опциям конфига мы можем прибегнуть к директиве extends 1 Создаём tsconfg-checks.json 2 Создаём tsconfig.json 3 В tsconfig.json пишем: gist.github.com/barinbritva/cf… Теперь полный порядок! 😉
notion image