Введение: Почему tsconfig.json — это не просто файл?
Каждый, кто хоть раз писал на TypeScript, сталкивался с загадочным файлом tsconfig.json. Если вы новичок, то скорее всего просто копировали его из документации или гуглили «как сгенерировать tsconfig.json». А если вы опытный разработчик — возможно, вы когда-то задавались вопросом: а что на самом деле происходит под капотом, когда я запускаю tsc --init?
В этой статье мы не просто дадим готовый рецепт, а заглянем в машинное отделение компилятора TypeScript. Вы узнаете, как компилятор читает конфигурацию, какие флаги отвечают за строгость кода, и как написать свой минимальный «генератор» tsconfig.json на коленке. Поехали!
1. Что такое tsconfig.json и зачем он нужен?
tsconfig.json — это JSON-файл, который говорит компилятору TypeScript (tsc), как именно обрабатывать ваш код. Без него tc будет работать в режиме «по умолчанию», но часто этого недостаточно для серьёзных проектов.
Под капотом tsconfig.json определяет:
- Какие файлы компилировать (ключ
include,exclude,files). - Куда складывать результат (ключ
outDir). - Какие версии JavaScript поддерживать (ключ
target). - Как строго проверять типы (ключи
strict,noImplicitAnyи др.). - Дополнительные модули и пути.
Когда вы задаёте вопрос «how can I generate a tsconfig.json file», ответ обычно один: tsc --init. Но давайте разберёмся, что именно генерирует эта команда.
2. Команда tsc --init: что под капотом?
Запустите в терминале:
npx tsc --init
В корне проекта появится файл tsconfig.json с кучей закомментированных настроек. На самом деле, под капотом компилятор TypeScript выполняет следующий алгоритм:
- Проверяет, существует ли уже
tsconfig.jsonв текущей директории. - Если нет — создаёт шаблон с настройками по умолчанию.
- Устанавливает
target: "es2016",module: "commonjs",strict: trueи другие разумные значения. - Все остальные опции комментирует, чтобы разработчик мог их раскомментировать при необходимости.
Но что если вы хотите кастомизировать генерацию? Например, сразу включить строгий режим или задать путь для выходных файлов? Для этого можно написать свой скрипт.
2.1. Пример: свой генератор tsconfig.json на TypeScript
Представьте, что вы пишете инструмент для автоматической настройки проектов. Вот как может выглядеть функция, которая генерирует tsconfig.json под капотом:
import * as fs from 'fs';
import * as path from 'path';
interface TsConfig {
compilerOptions: {
target: string;
module: string;
strict: boolean;
outDir: string;
rootDir: string;
esModuleInterop: boolean;
skipLibCheck: boolean;
forceConsistentCasingInFileNames: boolean;
};
include: string[];
exclude: string[];
}
function generateTsConfig(
target: string = 'ES2020',
outDir: string = './dist',
rootDir: string = './src',
strict: boolean = true
): TsConfig {
return {
compilerOptions: {
target,
module: 'commonjs',
strict,
outDir,
rootDir,
esModuleInterop: true,
skipLibCheck: true,
forceConsistentCasingInFileNames: true,
},
include: ['src/**/*'],
exclude: ['node_modules', 'dist'],
};
}
// Генерируем и сохраняем
const config = generateTsConfig();
fs.writeFileSync(
path.join(process.cwd(), 'tsconfig.json'),
JSON.stringify(config, null, 2)
);
console.log('tsconfig.json создан!');
Этот код — упрощённая версия того, что делает tsc --init. Под капотом компилятор делает то же самое, но с гораздо большим количеством проверок и опций.
3. Разбираем ключевые опции tsconfig.json
Когда вы генерируете tsconfig.json, важно понимать, за что отвечает каждая опция. Давайте разберём самые важные — те, которые чаще всего встречаются в вопросах на Stack Overflow.
3.1. strict: true — почему это важно?
Опция strict — это «главный выключатель» для целого семейства строгих проверок типов. Когда она включена, TypeScript под капотом активирует:
noImplicitAny— запрещает неявный типany.strictNullChecks— заставляет учитыватьnullиundefined.strictFunctionTypes— более строгая проверка функций.strictBindCallApply— проверка методовbind,call,apply.strictPropertyInitialization— проверка инициализации свойств класса.noImplicitThis— запрещает неявныйthisс типомany.alwaysStrict— включает строгий режим JavaScript.
Пример: без strictNullChecks вы можете случайно обратиться к свойству null:
// Без strictNullChecks — ошибки нет, но в рантайме будет падение
const user = null;
console.log(user.name); // Ошибка: Cannot read properties of null
С включённым strict TypeScript под капотом не даст вам этого сделать:
// Со strict — ошибка компиляции
const user: null = null;
console.log(user.name); // Object is possibly 'null'.
3.2. target и module: что выбирать?
Опция target определяет, в какую версию JavaScript будет транспилирован ваш код. Под капотом компилятор преобразует современный синтаксис (например, стрелочные функции, async/await) в более старый, понятный старым браузерам или средам.
ES5— для поддержки Internet Explorer и старых браузеров.ES2015/ES6— современные браузеры.ES2020— новейшие возможности, включая BigInt и динамический импорт.ESNext— самая последняя версия (рискованно для продакшена