Перейти к содержимому
Теория · Проект на TypeScript · урок 5 из 10

tsconfig.json

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

У проекта на TypeScript тоже есть правила для tsc: проверять строго, писать JavaScript в отдельную папку, не записывать файлы, пока в коде есть ошибки. Их можно каждый раз набирать флагами:

TEXT
$ tsc --strict --noEmitOnError --outDir dist src/main.ts

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

Файл tsconfig.json

Положим исходники в папку src, а рядом с ней — tsconfig.json:

TEXT
shop/
    tsconfig.json
    src/
        format.ts
        main.ts

Вот правила проекта:

TEXT
{
    "compilerOptions": {
        "target": "es2022",
        "module": "nodenext",
        "strict": true,
        "rootDir": "src",
        "outDir": "dist",
        "noEmitOnError": true
    },
    "include": ["src"]
}

Это JSON: объект, как в JavaScript, только ключи всегда в двойных кавычках. В compilerOptions собраны настройки компилятора, а include говорит, какие файлы проверять.

Теперь tsc запускают без имён файлов:

TEXT
$ tsc
$ node dist/main.js
100.00

Без имён файлов tsc находит tsconfig.json в текущей папке, читает правила и компилирует всё, что перечислено в include. JavaScript появляется в папке dist: dist/main.js и dist/format.js.

Настройки компилятора

target

target — версия JavaScript, которую пишет tsc. Если в этой версии нет какой-то возможности языка, tsc перепишет код без неё. Оператор ?? появился в JavaScript в 2020 году. Поэтому с "target": "es2019" строка city ?? "-" превратится в city !== null && city !== void 0 ? city : "-" (void 0 в JavaScript даёт undefined), а с "es2022" останется как есть.

module

module — в каком виде tsc записывает import и export. Значение "nodenext" значит «так, как их прочитает Node.js».

strict

strict включает строгий режим. С TypeScript 6.0 он включён и без этой строки, но её пишут, чтобы правило было видно в файле. Строгий режим — это группа проверок, и у каждой своё имя:

  • strictNullChecks — null и undefined считаются отдельными типами, и null нельзя положить в переменную типа string;
  • noImplicitAny — параметр без типа считается ошибкой TS7006, а не молча получает тип any.

Одну проверку можно выключить, не трогая остальные: "noImplicitAny": false рядом с "strict": true. В курсе все проверки строгого режима включены.

rootDir и outDir

rootDir — папка с исходниками, outDir — папка, куда tsc пишет JavaScript. Из src/main.ts получится dist/main.js. Если в tsconfig.json задан outDir, а исходники лежат в подпапке, TypeScript 7 требует назвать её в rootDir. Без этой строки он остановится:

TEXT
error TS5011: The common source directory of 'tsconfig.json' is './src'. The 'rootDir' setting must be explicitly set to this or another path to adjust your output's file layout.

noEmitOnError

noEmitOnError запрещает записывать JavaScript, пока в коде есть ошибки. Это тот же флаг --noEmitOnError, только записанный один раз для всего проекта.

include

include — список папок и файлов, которые проверяет tsc. Запись ["src"] значит «все файлы .ts в папке src и во вложенных в неё папках».

Вопрос с собеседования

На собеседовании часто спрашивают, что такое tsconfig.json и что делает strict. Ответ: это файл с настройками tsc для всего проекта, а strict включает группу строгих проверок, среди них strictNullChecks и noImplicitAny.

Когда tsc читает правила

Здесь аналогия с правилами на стене перестаёт работать. Правила в доме действуют на каждого, кто вошёл. А tsc читает tsconfig.json, только когда его запустили без имён файлов.

Частая ошибка

По привычке запустить tsc с именем файла в папке, где лежит tsconfig.json:

TEXT
$ tsc src/main.ts
error TS5112: tsconfig.json is present but will not be loaded if files are specified on commandline. Use '--ignoreConfig' to skip this error.

С именем файла tsc не читает tsconfig.json, и файл проверился бы с настройками по умолчанию, а не по правилам проекта. TypeScript 7 не даёт ошибиться молча и останавливается с этим сообщением.

Запускайте tsc без имён файлов. Если нужно проверить один файл без правил проекта, добавьте флаг из сообщения: tsc --ignoreConfig src/main.ts. Тогда main.js появится рядом с main.ts, а не в dist.

Главное

  • tsconfig.json хранит правила tsc для проекта: настройки в compilerOptions и список файлов в include.
  • tsc без имён файлов читает tsconfig.json и компилирует весь проект.
  • strict включает группу проверок, среди них strictNullChecks и noImplicitAny; с TypeScript 6.0 он включён по умолчанию.
  • Если рядом лежит tsconfig.json, команда tsc с именем файла в TypeScript 7 останавливается с ошибкой TS5112.