Menu

tsconfig.json в TypeScript: параметры, значения и примеры

tsconfig.json помечает папку как проект TypeScript и задаёт параметры компилятора. Важные параметры (target, module, moduleResolution, strict, rootDir, outDir, include, lib, types, noEmit, skipLibCheck), рекомендуемая стартовая конфигурация, extends и что изменилось в TypeScript 7.

На этой странице есть исполняемые редакторы: меняйте, запускайте и сразу видите результат.

tsconfig.json это файл конфигурации проекта TypeScript. Когда вы запускаете tsc без аргументов, компилятор ищет его в текущей папке (затем в родительских), читает параметры из compilerOptions и проверяет файлы, перечисленные в include. Небольшой, но полный пример:

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

Эта конфигурация компилирует все файлы TypeScript из src в JavaScript в dist в виде кода ES2022 по правилам модулей Node.js, со всеми строгими проверками. npx tsc --init генерирует более длинный стартовый файл с комментарием к каждому параметру.

Файл имеет формат JSON с комментариями: допускаются комментарии //, комментарии /* */ и завершающие запятые.

Рекомендуемая стартовая конфигурация

Для приложения или скрипта на Node.js:

{
    "compilerOptions": {
        "rootDir": "./src",
        "outDir": "./dist",

        "target": "es2024",
        "lib": ["es2024"],
        "module": "nodenext",
        "types": ["node"],

        "strict": true,
        "noUncheckedIndexedAccess": true,
        "verbatimModuleSyntax": true,
        "skipLibCheck": true,
        "sourceMap": true
    },
    "include": ["src"]
}

Для типов Node.js нужен npm install --save-dev @types/node. С module: "nodenext" поле "type" в package.json решает, будет ли файл .ts модулем ES ("type": "module") или CommonJS ("type": "commonjs", его записывает npm init -y). Для новых проектов с import и export используйте "type": "module".

Для кода, который собирает бандлер вроде Vite, esbuild или webpack, JavaScript пишет бандлер, а tsc только проверяет:

{
    "compilerOptions": {
        "target": "es2022",
        "lib": ["es2022", "dom"],
        "module": "preserve",
        "noEmit": true,

        "strict": true,
        "noUncheckedIndexedAccess": true,
        "verbatimModuleSyntax": true,
        "isolatedModules": true,
        "skipLibCheck": true,
        "jsx": "react-jsx"
    },
    "include": ["src"]
}

Стартовые шаблоны фреймворков (Vite, Next.js, Angular) генерируют собственный tsconfig.json. Начинайте с него, а не заменяйте его.

Важные параметры

ПараметрЧто делаетЗначение по умолчанию в TypeScript 7
targetВерсия JavaScript на выходе; новый синтаксис переписывается для старых целейes2025
libТипы встроенных API, о которых знает проверка (Array.prototype.at, Map, document)Соответствует target, плюс DOM
moduleКакой модульный код генерируется и какие правила модулей действуютesnext
moduleResolutionКак пути импорта ищутся на дискеnodenext или node16 с соответствующим module, иначе bundler
strictВключает всё семейство строгих проверокtrue
rootDirПапка, структура которой повторяется в outDirПапка, где лежит tsconfig.json
outDirКуда попадают файлы .js (и .d.ts)Рядом с каждым исходным файлом
include / exclude / filesКакие файлы входят в проектВсе файлы .ts внутри папки
typesКакие пакеты @types загружаются без импорта[], никакие
noEmitТолько проверка, ничего не записыватьfalse
declarationТакже записывать файлы объявлений типов .d.tsfalse
sourceMapЗаписывать файлы .js.map для отладчиковfalse
esModuleInteropПозволяет import x from "cjs-package" работать с пакетами CommonJStrue (выключить нельзя)
skipLibCheckНе проверять типы в файлах .d.ts, включая файлы в node_modulesfalse

target и lib

target указывает, на какой версии JavaScript должен работать результат. Синтаксис новее целевой версии переписывается: с "target": "es2017" поле класса или ??= превращается в более старый код. Самая низкая цель, которую принимает TypeScript 7, это es2015 (es6); es5 удалена.

target не добавляет недостающие API времени выполнения. Описывать их это задача lib, а предоставлять их задача полифила. lib сообщает проверке типов, какие встроенные объекты и методы существуют. Его значение по умолчанию следует за target и включает также типы DOM браузера, поэтому document проходит проверку даже в проекте на Node.js, если вы не зададите lib сами. Использование метода из стандарта новее вашего lib это ошибка компиляции:

src/b.ts(1,24): error TS2550: Property 'toSorted' does not exist on type 'number[]'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2023' or later.

Запускаемые примеры в этой документации используют lib es2022, поэтому toSorted, Object.groupBy и новые методы Set в них недоступны.

module и moduleResolution

У module есть три разумных значения для нового кода:

  • nodenext: для кода, который запускает Node.js. Каждый файл считается ESM или CommonJS по расширению (.mts, .cts) или по полю "type" ближайшего package.json, ровно так, как решает Node. Относительным импортам в модулях ES нужно расширение файла, причём пишется .js, хотя исходник это .ts: import { add } from "./math.js". moduleResolution подстраивается автоматически.
  • preserve: для кода, который обрабатывает бандлер. Импорты остаются как написаны, а разрешение идёт по правилам bundler, которые допускают импорты без расширений.
  • esnext: обычный вывод модулей ES с разрешением bundler. Это значение по умолчанию, если module не задан.

Частая первая ошибка с конфигурацией из tsc --init возникает из-за того, что npm init -y записывает "type": "commonjs":

src/main.ts(1,10): error TS1295: ECMAScript imports and exports cannot be written in a CommonJS file under 'verbatimModuleSyntax'.

Файл использует import, а package.json говорит, что проект на CommonJS. Замените "type" на "module". Импорты и экспорты подробно разобраны на странице о модулях.

strict и параметры проверки

"strict": true включает сразу группу проверок: noImplicitAny, strictNullChecks, strictFunctionTypes, strictBindCallApply, strictPropertyInitialization, strictBuiltinIteratorReturn, noImplicitThis и useUnknownInCatchVariables. В TypeScript 7 он включён по умолчанию и включён во всех запускаемых примерах здесь. Код для строгого режима сужает тип, прежде чем использовать значение, которого может не быть:

Без аннотации тип параметра вывести нельзя, и noImplicitAny сообщает об этом:

index.ts(2,17): error TS7006: Parameter 'n' implicitly has an 'any' type.

strict включает не все полезные проверки. Стоит добавить ещё две: noUncheckedIndexedAccess (элемент массива или значение по сигнатуре индекса имеет тип T | undefined) и exactOptionalPropertyTypes (необязательному свойству нельзя явно присвоить undefined); tsc --init включает обе. Стилевые проверки вроде noUnusedLocals, noImplicitReturns и noFallthroughCasesInSwitch по умолчанию выключены.

Какие файлы: include, exclude, rootDir, outDir

Без include или files проект содержит все файлы .ts, .tsx и .d.ts в папке и её подпапках. node_modules исключается всегда. outDir тоже исключается, но только пока вы не задали exclude: собственный список exclude заменяет это поведение по умолчанию, поэтому добавьте в него папку вывода. include и exclude принимают glob-шаблоны:

{
    "include": ["src", "scripts/**/*.ts"],
    "exclude": ["src/**/*.test.ts"]
}

exclude только фильтрует то, что нашёл include. Файл, который импортирует другой включённый файл, всё равно компилируется.

outDir это место для результатов, а rootDir это часть дерева исходников, которая в нём повторяется: с "rootDir": "./src" файл src/api/users.ts становится dist/api/users.js. Задавайте оба. По умолчанию rootDir это папка, где лежит tsconfig.json, поэтому если задать только outDir, а исходники лежат в src, TypeScript 7 остановится с ошибкой:

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.

Параметры вывода: noEmit, declaration, sourceMap

  • "noEmit": true превращает tsc в чистую проверку типов. Используйте его, когда JavaScript создаёт другой инструмент (бандлер, tsx, удаление типов в Node.js).
  • "declaration": true записывает файл .d.ts для каждого модуля, то есть типы без кода. Он нужен библиотекам, чтобы их пользователи получали типы. declarationMap добавляет карты для перехода к определению в исходнике .ts.
  • "sourceMap": true записывает файлы .js.map, чтобы отладчики и трассировки стека указывали на строки .ts.
  • "noEmitOnError": true ничего не записывает, пока есть ошибки типов. Без него tsc сообщает об ошибках и всё равно записывает JavaScript.

types, esModuleInterop и skipLibCheck

types перечисляет пакеты @types, которые загружаются глобально, без импорта. В TypeScript 7 по умолчанию это пустой список, поэтому после npm install --save-dev @types/node добавьте ещё "types": ["node"]; иначе process и require останутся неизвестными (error TS2591: Cannot find name 'process'). Тестовые раннеры с глобальными функциями, например describe в Jest, добавляются в тот же список.

esModuleInterop позволяет импортировать по умолчанию пакеты CommonJS (import express from "express"). В TypeScript 7 он всегда включён, и значение false это ошибка.

skipLibCheck пропускает проверку типов в файлах объявлений. Он ускоряет сборку и убирает ошибки внутри node_modules, которые вы всё равно не можете исправить, но зато вы не заметите конфликта между типами двух библиотек. Большинство проектов его включают.

Общие настройки через extends

extends загружает другую конфигурацию и позволяет этому файлу переопределить её части:

{
    "extends": "./tsconfig.base.json",
    "compilerOptions": {
        "rootDir": "./src",
        "outDir": "./dist"
    },
    "include": ["src"]
}

compilerOptions объединяются по каждому параметру, а include, exclude и files из базового файла заменяются, а не объединяются, если этот файл их задаёт. Пути в базовом файле разрешаются относительно базового файла. extends принимает и пакет: проект @tsconfig/bases публикует по одному для каждого окружения, например npm install --save-dev @tsconfig/node24 и затем "extends": "@tsconfig/node24/tsconfig.json".

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

npx tsc --showConfig

Параметры, удалённые в TypeScript 7

TypeScript 6 объявил эти настройки устаревшими, а TypeScript 7 их удалил. Конфигурация, которая всё ещё использует одну из них, завершается ошибкой error TS5108 или TS5102, например Option 'baseUrl' has been removed. Please remove it from your configuration.

Удалённая настройкаЧто использовать вместо
"target": "es5"es2015 или новее
"moduleResolution": "node" (node10) или "classic"nodenext или bundler
"module": "amd", "umd", "system", "none"nodenext, esnext или preserve, а для других форматов бандлер
baseUrlЗаписи paths относительно файла tsconfig
outFileБандлер
downlevelIterationНичего: цели начиная с es2015 поддерживают итерацию нативно
"esModuleInterop": false, "allowSyntheticDefaultImports": false, "alwaysStrict": falseУдалите строку; эти параметры всегда включены

Другие изменения этого выпуска, включая новые значения по умолчанию, которых нет в этой таблице, перечислены на странице о TypeScript 7.

Часто задаваемые вопросы

Что такое tsconfig.json?

Это файл конфигурации проекта TypeScript. Его наличие помечает папку как корень проекта, compilerOptions задаёт, как компилятор проверяет и генерирует код, а include, exclude или files указывают, какие файлы входят в проект. Команда tsc без аргументов читает именно его.

Как создать файл tsconfig.json?

Выполните npx tsc --init в папке проекта (с установленным TypeScript). Команда запишет tsconfig.json с рекомендуемыми настройками и комментарием к каждому параметру. Файл можно написать и вручную; {} это корректный tsconfig, в котором действуют все значения по умолчанию.

Какое значение target указать в tsconfig?

Самую старую версию JavaScript, на которой должен работать ваш код. Для современного Node.js безопасно es2022 или новее; по умолчанию TypeScript 7 использует es2025. target определяет, какой новый синтаксис переписывается для старых движков, а также выбирает lib по умолчанию, то есть набор встроенных API, о которых знает проверка типов.

Чем module отличается от moduleResolution?

module определяет, какой модульный код пишет компилятор (ES import/export или CommonJS require) и какие правила модулей действуют. moduleResolution определяет, как путь импорта вроде "./utils.js" или "lodash" ищется на диске. Используйте nodenext для кода, который запускает Node.js, и module: "preserve" (он подразумевает разрешение bundler) для кода, который обрабатывает бандлер.

Можно ли писать комментарии в tsconfig.json?

Да. Компилятор читает его как JSON с комментариями: допускаются комментарии // и /* */ и завершающие запятые, поэтому tsc --init и создаёт файл с кучей закомментированных параметров. Другие инструменты, которые разбирают его как строгий JSON, могут на этом споткнуться.

Coddy programming languages illustration

Учитесь программировать с Coddy

НАЧАТЬ