Что обозначает watch в tsconfig json
TypeScript: Раскладываем tsconfig по полочкам. Часть 1
Итак, в данной статье я хочу предоставить переработанную и упорядоченную выжимку документации, которая, я уверен, будет полезна тем, кто только начинает свой путь в мире TypeScript или тем, кто до этого момента не нашёл времени и сил, чтобы разобраться в деталях и теперь хочет закрыть этот пробел.
Все опции, как и саму статью, я разделил на две группы – базовые и «проверки». В первой части статьи разговор пойдёт про базовые настройки, а во второй уже про различные проверки, т. е. про тюнинг строгости компилятора.
Структура tsconfig
Рассмотрим структуру и некоторые особенности конфига.
tsconfig.json поддерживает комментарии. Такие IDE как WebStorm и Visual Studio Code знают об этом и не выделяют комментарии как синтаксическую ошибку
tsconfig.json поддерживает наследование. Опции можно разделить по некоторому принципу, описать их в разных файлах и объединить с помощью специальной директивы
Это болванка нашего tsconfig.json :
Иногда в root секции конфига можно встретить такие опции как compileOnSave и ts-node . Эти опции не являются официальными и используются IDE для своих целей.
Секция root
extends
Type: string | false, default: false.
Указывает путь к файлу из которого нужно унаследовать опции. По большей части, служит инструментом упорядочивания. Можно разделить опции по некой логике, чтобы они не смешивались. Например, вынести настройки строгости в отдельный файл, как в примере болванки конфига. Однако, учитывая поддержку комментариев в tsconfig.json это можно сделать проще:
Рассмотрим другой use-case, где комментариями отделаться не получится. Если необходимо создать production и development конфиги. Так бы мог выглядеть tsconfig-dev.json версия конфига:
files
Type: string[] | false, default: false, связана с include .
Указать список конкретных файлов для компиляции можно использовав данную опцию.
Данная опция подходит лишь для совсем маленьких проектов из нескольких файлов.
include
Type string[], default: зависит от значения files , связана с exclude .
exclude
Type: string[], default: [«node_modules», «bower_components», «jspm_packages»].
Опция exclude не может исключить файлы, указанные через files .
Опция exclude не может исключить файлы, если они импортируются в других файлах, которые не исключены.
Секция compilerOptions
target
Type: string, default: ES3 , влияет на опции lib , module .
module
Type: string, default: зависит от target , влияет на опцию moduleResolution .
Если ваша ситуация не такая простая или хотите знать все тонкости модульных систем, тогда придётся всё-таки изучить подробную документацию.
moduleResolution
Type: string, default: зависит от module .
Во избежание описанной ситуации, я рекомендую всегда явно указывать значение node для данного флага.
Type: string[], default: зависит от target .
Конечно, правильным выбором будет подключать тайпинги только той функциональности, для которой установлены полифилы.
Как только вы что-либо добавляете в lib умолчания сбрасываются. Необходимо руками добавить то, что нужно, например DOM :
outDir
Type: string, default: равняется корневой директории.
Если оставить опцию outDir пустой:
Если указать outDir :
outFile
Type: string, default: none.
allowSyntheticDefaultImports
Type: boolean, default: зависит от module или esModuleInterop .
Опция включена по умолчанию, если включен флаг esModuleInterop или module === «system».
esModuleInterop
Type: boolean, default: false.
Данный флаг по зависимости активирует allowSyntheticDefaultImports . Вместе они помогают избавиться от зоопарка разных импортов и писать их единообразно по всему проекту.
alwaysStrict
Type: boolean, default: зависит от strict .
Компилятор будет парсить код в strict mode и добавлять “use strict” в выходные файлы.
downlevelIteration
Type: boolean, default: false.
Для работы данного флага, необходимо, чтобы в браузере была реализация Symbol.iterator . В противном случае необходимо установить полифил.
forceConsistentCasingInFileNames
Type: boolean, default: false.
Опции секции compilerOptions, которые нужны не в каждом проекте
declaration
Type: boolean, default: false.
declarationDir
Type: string, default: none, связан с declaration .
emitDeclarationOnly
Type: boolean, default: false, связан с declaration .
allowJs
Type: boolean, default: false.
checkJs
Type: boolean, default: false, связан с allowJs .
С версии 4.1 при включении checkJs , флаг allowJs включается автоматически.
experimentalDecorators и emitDecoratorMetadata
Type: boolean, default: false.
Флаг experimentalDecorators просто активирует синтаксис, а emitDecoratorMetadata в рантайме предоставляет декораторам дополнительные мета-данные, с помощью которых можно значительно расширить области применения данной фичи.
Для работы emitDecoratorMetadata необходимо подтянуть в проект библиотеку reflect-metadata.
resolveJsonModule
Type: boolean, default: false.
Флаг позволяет включить возможность импортировать *.json файлы. Ничего дополнительно устанавливать не требуется.
Type: string, default: none.
Завершение первой части
В этой статье я расписал самые важные флаги и опции, которые могут понадобиться в подавляющем большинстве проектов. В следующей же части я расскажу про настройку строгости компилятора.
UPD: Здесь можно прочитать вторую часть статьи.
TypeScript: Раскладываем tsconfig по полочкам. Часть 2 — Всё про строгость
В прошлой статье я рассказал о различных особенностях некоторых общих настроек TypeScript. В данной статье речь пойдёт о так называемых «флагах строгости».
На самом деле, TypeScript из коробки мало чем отличается от JavaScript. Поэтому если изначально не подтюнить конфиг проекта, то большая часть преимуществ языка не будет задействована. Смысл использования TypeScript в таком виде есть, но небольшой.
Группа Strict Checks
alwaysStrict
Рекомендован: всегда / сложность: легко.
Флаг alwaysStrict включает добавление строки «use strict» в каждый скомпилированный файл. Другими словами, alwaysStrict включает строгий режим JavaScript и никак не связан с проверкой типов TypeScript.
strict
Рекомендован: всегда / сложность: сложно / может быть заменён набором других флагов.
Есть небольшая особенность работы флага strict – список подконтрольных ему флагов может пополняться по мере выхода новых версий TypeScript. Подобные моменты если случаются, то редко и всегда освещаются в release notes если, конечно, вы их читаете перед обновлением версии.
Лично я предпочитаю указывать список флагов явным образом:
Рассмотрим, что делает каждый из флагов и обсудим какие из них стоит включить в первую очередь, если активировать сразу все не получается.
noImplicitAny
Рекомендую: всегда / сложность: средне
Это первый флаг, который необходимо активировать в начале работы над проектом с TypeScript.
Для компилятора тип any означает «это может быть что угодно, передаю управление и ответственность разработчику». Так как компилятор не знает тип переменной, с такой переменной можно делать всё что угодно. В этом месте TypeScript полностью лишён своей силы:
strictNullChecks
Рекомендую: всегда / сложность: средне
Подобное поведение справедливо для почти всех (если не всех) языков программирования. На практике это может вызывать неудобства в виде написания дополнительных проверок на null ( undefined ). Но гораздо большей проблемой является помнить о необходимости покрывать код данными проверками. Думаю, Java разработчики с их NullPointerException как никто другой понимают эту проблему.
Включение опции strictNullChecks меняет правила игры. С данным флагом компилятор больше не позволяет передавать undefined или null туда, где ожидаются переменные других типов, если это не разрешено явно. Рассмотрим пример:
Это позволяет не обрабатывать ситуации с undefined и null в тех участках кода, где возникновение данных значений невозможно. При этом в тем местах, где возникновение подобных ситуаций возможно, компилятор не позволит забыть о проверках. Это очень сильный механизм, существование которого сложно переоценить.
Чуть более коварной может быть ситуация с внешними библиотеками. В частности, с теми, который изначально написаны на JavaScript и тайпинги для них существуют отдельно от кода. В таких случаях потенциальные несовпадения реального кода с типами могут привести к возникновению вышеописанной ситуации.
strictPropertyInitialization
Рекомендую: всегда / сложность: легко / связан с strictNullChecks
Флаг strictPropertyInitialization следит, чтобы объявленные свойства класса всегда были инициализированы:
Опция является своего рода дополнением к флагу strictNullChecks поэтому работает только когда второй флаг тоже включен.
strictFunctionTypes
Рекомендую: всегда / сложность: легко
Установка флага strictFunctionTypes: true включает более строгую проверку сигнатур функций. В целом, данная опция выглядит достаточно обязательной для использования:
noImplicitThis
Рекомендую: всегда / сложность: легко
При использовании this проверяет, что контекст выполнения известен. Рассмотрим такой пример:
Рассмотрим пример независимой функции, которая по каким-то причинам должна использовать внешний this :
Во всех случаях тип контекста известен и даже тайпхинтинг работает как следует.
strictBindCallApply
Рекомендую: всегда / сложность: средне
Кроме некоторых специфичных ситуаций при работе с данным флагом проблем не возникает. В случае возникновения сложных ситуаций рекомендую выключить проверку в месте возникновения проблемы через комментарий // @ts-ignore вместо полного отключения правила.
Подведение итогов Strict Checks
здесь действительно все флаги очень полезные. С ними TypeScript раскрывает свой потенциал и приносит максимум пользы
все флаги можно включить разом через strict: true или каждый по отдельности. Второй вариант отлично подходит для смешанных кодовых баз, где часть кода ещё не переведена на TypeScript.
Группа Linter Checks
Название группы говорит само за себя – подразумевается, что флаги этой группы проверяют не соответствие типов, а качество кода. Своего рода правила как в ESLint. И действительно некоторые правила секции Linter Checks можно заменить на аналогичные правила ESLint. Полный список флагов данной секции:
Остальные же флаги группы полноправно находятся в этой секции и имеют аналогичные правила в ESLint. В некоторых случаях с временными ограничениями, так как ещё не все правила перенесены в ESLint из TSLint. Соответствия правил можно посмотреть на странице TSLint Migration Guide и в репозитории ESLint rules for TSLint.
Рассмотрим работу каждого из флагов.
noPropertyAccessFromIndexSignature
Рекомендую: всегда / сложность: легко / есть нюанс / нельзя заменить линтером
Единственной причиной не использовать данную опцию – наличие двух видов синтаксиса для обращения к свойствам объекта. Однако на мой взгляд в этом нет проблемы так как хоть синтаксис и разный, у каждого из них есть своё назначение. Всегда используем dot notation и, если случается исключение, переходим на скобочную нотацию. При этом код становится безопаснее. Поэтому я рекомендую использовать этот флаг.
noUncheckedIndexedAccess
Рекомендую: по ситуации / сложность: средне / есть серьёзный нюанс / связан с strictNullChecks / нельзя заменить линтером
Ещё раз взглянем на предыдущий пример.
Флаг noUncheckedIndexedAccess сделает эту работу за нас. Теперь компилятор не позволит использовать полученные таким образом переменные без предварительной проверки.
Рассмотрим ещё один пример. На этот раз с массивом:
Казалось бы, мы подчеркнули скобочной нотацией «магические» свойства объекта, мы можем использовать их только после проверок на undefined – всё красиво и безопасно. Что может пойти не так?
Другими словами, при данной конфигурации в обмен на безопасность в некоторых случаях придётся платить проверками, которые не несут смысла только для того, чтобы укротить строптивый компилятор. Выглядит это крайне костыльно.
Определённо код с noUncheckedIndexedAccess становится значительно безопаснее, а это главная цель использования TypeScript. Однако компромисс может выглядеть достаточно серьёзным, поэтому я не могу рекомендовать флаг всем разработчикам.
Флаг является своего рода дополнением к флагу strictNullChecks поэтому работает только когда второй флаг тоже включен.
noImplicitReturns
Рекомендую: всегда / сложность: легко / правило ESLint: consistent-return, пока не реализовано
Флаг проверяет, чтобы все ветки функции возвращали значение:
noFallthroughCasesInSwitch
Рекомендую: если не используется ESLint / сложность: легко / правило ESLint: no-fallthrough
Флаг проверяет наличие break в операторе switch/case :
noUnusedLocals
Рекомендую: для production если не используется ESLint / сложность: легко / правило ESLint: no-unused-vars
Код проверяется на наличие неиспользуемых переменных:
Данное правило крайне неудобно при использовании в процессе разработки. В процессе написания кода он может находится в «разобранном» состоянии, а наличие неиспользуемых переменных будет вызывать ошибку компиляции.
noUnusedParameters
Рекомендую: для production если не используется ESLint / сложность: легко / правило ESLint: no-unused-vars
Код проверяется на наличие неиспользуемых аргументов функций и методов:
Подведение итогов Linter Checks
нет единого флага, которым можно активировать все опции секции
Группа Advanced
Это самая большая секция и кажется, что в неё поместили все опции, которым не нашлось отдельных групп. Из них часть опций относится к настройкам строгости компилятора. Вот они:
Эти флаги по умолчанию false и должны быть false для строгости!
Вот мы и нашли те опции, которые включены по умолчанию и составляют типобезопасность TypeScript из коробки!
По сути, вышеперечисленные опции (кроме noImplicitUseStrict ) включают явные нарушения типизации, что в некоторых случаях можно использовать как временное решение при портировании сложных участков кода с JavaScript.
Ни один флаг из данной четвёрки не придётся переопределять в 99.9% случаев.
Теперь буквально по паре слов об этой псевдо-группе опций.
allowUnreachableCode
Рекомендую: всегда для production / сложность: легко / правило ESLint: no-unreachable, пока не реализовано
Флаг запрещает недосягаемый код – код, написанный после операторов return, throw, break, continue:
allowUnusedLabels
Рекомендую: для production если не используется ESLint / сложность: легко / правило ESLint: no-unused-labels
Опция запрещает неиспользуемые лэйблы. Не думаю, что можно встретить данную синтаксическую конструкцию в наши дни, но тем не менее:
noImplicitUseStrict
Настроен по умолчанию, изменять противопоказано / связан с alwaysStrict
suppressExcessPropertyErrors
Настроен по умолчанию, изменять противопоказано
Флаг проверяет, чтобы объект не мог содержать свойства, которые не были описаны в его структуре:
suppressImplicitAnyIndexErrors
Настроен по умолчанию, изменять противопоказано / связан с noImplicitAny
Флаг проверяет, что используя скобочную нотацию невозможно обращаться к свойствам объекта, которые в нём не объявлены ни явно, ни через произвольные параметры. Вспомним пример флага noUncheckedIndexedAccess и удалим из него произвольные параметры:
Рассмотрим пример. Мы подключили некую библиотеку, допустим Google Maps, через тэг script. Попробуем создать объект Pin:
Конечно, здесь будет ошибка, так как встроенные тайпинги ничего не знают о свойстве google. Использовать // @ts-ignore проблематично, так как его придётся писать чуть ли на каждой строчке кода. Поэтому часто можно встретить такое решение – ставим suppressImplicitAnyIndexErrors: true (разрешить допущение) и пишем код следующим образом:
Это имеет место быть в проектах на промежуточной стадии портирования. Но я бы не рекомендовал прибегать к подобной практике даже в этом случае. Подобная проблема решается использованием объединения деклараций:
Данная практика применима и к внешним библиотекам, например для расширения req и res объектов фреймворка Express.
noStrictGenericChecks
Настроен по умолчанию, изменять противопоказано
Переопределение данного флага может сделать компилятор «более лояльным» при работе с generics :
Подведём итоги Advanced
Секция состоит из большого количества не связанных между собой флагов. Часть из них относится к строгости компилятора. Эти флаги можно перераспределить в тематические секции
Флаги allowUnreachableCode и allowUnusedLabels относятся к линтингу, их можно было бы перенести в Linter Checks
Про остальные четыре флага можно забыть
Заключение
В качестве заключения я бы хотел написать шпаргалку со всеми упомянутыми флагами, которые обеспечивают максимальную строгость и наглядность:
А для удобства разработки, чтобы нам недостижимый код и неиспользуемые переменные не ломали компиляцию, можно сделать следующим образом.
На этом всё. В будущем планирую разобраться с опциями оптимизации и производительности и обязательно поделиться с вами. До новых встреч!
Что обозначает watch в tsconfig json
The presence of a tsconfig.json file in a directory indicates that the directory is the root of a TypeScript project. The tsconfig.json file specifies the root files and the compiler options required to compile the project.
JavaScript projects can use a jsconfig.json file instead, which acts almost the same but has some JavaScript-related compiler flags enabled by default.
A project is compiled in one of the following ways:
Using tsconfig.json or jsconfig.json
When input files are specified on the command line, tsconfig.json files are ignored.
Example tsconfig.json files:
Using the files property
Using the include and exclude properties
Depending on the JavaScript runtime environment which you intend to run your code in, there may be a base configuration which you can use at github.com/tsconfig/bases. These are tsconfig.json files which your project extends from which simplifies your tsconfig.json by handling the runtime support.
For example, if you were writing a project which uses Node.js version 12 and above, then you could use the npm module @tsconfig/node12 :
This lets your tsconfig.json focus on the unique choices for your project, and not all of the runtime mechanics. There are a few tsconfig bases already, and we’re hoping the community can add more for different environments.
The «compilerOptions» property can be omitted, in which case the compiler’s defaults are used. See our full list of supported Compiler Options.
To learn more about the hundreds of configuration options in the TSConfig Reference.
The tsconfig.json Schema can be found at the JSON Schema Store.
The TypeScript docs are an open source project. Help us improve these pages by sending a Pull Request ❤
Compiling TypeScript
TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. It offers classes, modules, and interfaces to help you build robust components. The TypeScript language specification has full details about the language.
Install the TypeScript compiler
You can test your install by checking the version or help.
Compiler versus language service
It is important to keep in mind that VS Code’s TypeScript language service is separate from your installed TypeScript compiler. You can see the VS Code’s TypeScript version in the Status Bar when you open a TypeScript file.
Later in the article, we’ll discuss how you can change the version of TypeScript language service that VS Code uses.
tsconfig.json
A simple tsconfig.json looks like this for ES5, CommonJS modules and source maps:
Transpile TypeScript into JavaScript
Step 1: Create a simple TS file
Open VS Code on an empty folder and create a helloworld.ts file, place the following code in that file.
Step 2: Run the TypeScript build
Execute Run Build Task ( ⇧⌘B (Windows, Linux Ctrl+Shift+B ) ) from the global Terminal menu. If you created a tsconfig.json file in the earlier section, this should present the following picker:
Select the tsc: build entry. This will produce a HelloWorld.js and HelloWorld.js.map file in the workspace.
If you selected tsc: watch, the TypeScript compiler watches for changes to your TypeScript files and runs the transpiler on each change.
Step 3: Make the TypeScript Build the default
Notice that the task has a group JSON object that sets the task kind to build and makes it the default. Now when you select the Run Build Task command or press ( ⇧⌘B (Windows, Linux Ctrl+Shift+B ) ), you are not prompted to select a task and your compilation starts.
Tip: You can also run the program using VS Code’s Run/Debug feature. Details about running and debugging Node.js applications in VS Code can be found in the Node.js tutorial
Step 4: Reviewing build issues
As an example, if there was a simple error (extra ‘g’ in console.log ) in our TypeScript file, we may get the following output from tsc :
You can see the error and warning counts in the Status Bar. Click on the error and warnings icon to get a list of the problems and navigate to them.
Tip: Tasks offer rich support for many actions. Check the Tasks topic for more information on how to configure them.
JavaScript source map support
In-lined source maps (a source map where the content is stored as a data URL instead of a separate file) are also supported, although in-lined source is not yet supported.
Output location for generated files
Having the generated JavaScript file in the same folder at the TypeScript source will quickly get cluttered on larger projects. You can specify the output directory for the compiler with the outDir attribute.
Hiding derived JavaScript files
When you are working with TypeScript, you often don’t want to see generated JavaScript files in the File Explorer or in Search results. VS Code offers filtering capabilities with a files.exclude workspace setting and you can easily create an expression to hide those derived files:
This pattern will match on any JavaScript file ( **/*.js ) but only if a sibling TypeScript file with the same name is present. The File Explorer will no longer show derived resources for JavaScript if they are compiled to the same location.
This is a bit of a trick. The search glob pattern is used as a key. The settings above use two different glob patterns to provide two unique keys but the search will still match the same files.
Using newer TypeScript versions
VS Code ships with a recent stable version of the TypeScript language service and uses this by default to provide IntelliSense in your workspace. The workspace version of TypeScript is independent of the version of TypeScript you use to compile your *.ts files. You can just use VS Code’s built-in TypeScript version for IntelliSense without worry for most common cases, but sometimes you may need to change the version of TypeScript VS Code uses for IntelliSense.
Reasons for doing this include:
The active TypeScript version and its install location are displayed in the Status Bar when viewing a TypeScript file:
You have a few options if you want to change the default version of TypeScript in your workspace:
Using the workspace version of TypeScript
If your workspace has a specific TypeScript version, you can switch between the workspace version of TypeScript and the version that VS Code uses by default by opening a TypeScript or JavaScript file and clicking on the TypeScript version number in the Status Bar. A message box will appear asking you which version of TypeScript VS Code should use:
Use this to switch between the version of TypeScript that comes with VS Code and the version of TypeScript in your workspace. You can also trigger the TypeScript version selector with the TypeScript: Select TypeScript Version command.
Note that while typescript.tsdk points to the lib directory inside of typescript in these examples, the typescript directory must be a full TypeScript install that contains the TypeScript package.json file.
You can also tell VS Code to use a specific version of TypeScript in a particular workspace by adding a typescript.tsdk workspace setting pointing to the directory of the tsserver.js file:
The typescript.tsdk workspace setting only tells VS Code that a workspace version of TypeScript exists. To actually start using the workspace version for IntelliSense, you must run the TypeScript: Select TypeScript Version command and select the workspace version.
Using TypeScript nightly builds
The simplest way to try out the latest TypeScript features in VS Code is to install the JavaScript and TypeScript Nightly extension.
This extension automatically replaces VS Code’s built-in TypeScript version with the latest TypeScript nightly build. Just make sure you switch back to using VS Code’s TypeScript version if you’ve configured your TypeScript version with the TypeScript: Select TypeScript Version command.
Mixed TypeScript and JavaScript projects
Working with large projects
If you are working in a codebase with hundreds or thousands of TypeScript files, here are some steps you can take to improve both the editing experience in VS Code as well as compile times on the command line.
Make sure your tsconfig only includes files you care about
Use include or files in your project’s tsconfig.json to make sure the project only includes the files that should be part of the project.
Break up your project using project references
Instead of structuring your source code as a single large project, you can improve performance by breaking it up into smaller projects using project references. This allows TypeScript to load just a subset of your codebase at a time, instead of loading the entire thing.
See the TypeScript documentation for details on how to use project references and best practices for working with them.
Next steps
Read on to find out about:
Common questions
How do I resolve a TypeScript «Cannot compile external module» error?
If you get that error, resolve it by creating a tsconfig.json file in the root folder of your project. The tsconfig.json file lets you control how Visual Studio Code compiles your TypeScript code. For more information, see the tsconfig.json overview.
Why do I get different errors and warnings with VS Code than when I compile my TypeScript project?
VS Code ships with a recent stable version of the TypeScript language service and it may not match the version of TypeScript installed globally on your computer or locally in your workspace. For that reason, you may see differences between your compiler output and errors detected by the active TypeScript language service. See Using newer TypeScript versions for details on installing a matching TypeScript version.
Can I use the version of TypeScript that ships with VS 2015?
No, the TypeScript language service that ships with Visual Studio 2015 and 2017 isn’t compatible with VS Code. You will need to install a separate version of TypeScript from npm.
Why are some errors reported as warnings?
By default, VS Code TypeScript displays code style issues as warnings instead of errors. This applies to:
Treating these as warnings is consistent with other tools, such as TSLint. These will still be displayed as errors when you run tsc from the command line.








