tsconfig.json
The house rules hang on the wall: where to leave your shoes, when to turn the music off. Nobody retells them to every guest. The rules are the same for everyone, and anyone can read them.
A TypeScript project also has rules for tsc: check strictly, write the JavaScript into a separate folder, write no files while the code has errors. You can type them as flags every time:
$ tsc --strict --noEmitOnError --outDir dist src/main.tsSuch a command has to be typed every time, and typos creep in. And a colleague runs tsc with other flags and gets a different result. That is why the rules are written down once, in a tsconfig.json file at the root of the project.
The tsconfig.json file
Let's put the sources into a src folder and tsconfig.json next to it:
shop/
tsconfig.json
src/
format.ts
main.tsHere are the project's rules:
{
"compilerOptions": {
"target": "es2022",
"module": "nodenext",
"strict": true,
"rootDir": "src",
"outDir": "dist",
"noEmitOnError": true
},
"include": ["src"]
}This is JSON: an object as in JavaScript, except that the keys are always in double quotes. compilerOptions gathers the compiler's settings, and include says which files to check.
Now tsc is run without file names:
$ tsc
$ node dist/main.js
100.00Without file names tsc finds tsconfig.json in the current folder, reads the rules and compiles everything listed in include. The JavaScript appears in the dist folder: dist/main.js and dist/format.js.
Compiler settings
target
target is the JavaScript version tsc writes. If that version lacks some language feature, tsc rewrites the code without it. The ?? operator appeared in JavaScript in 2020. So with "target": "es2019" the line city ?? "-" turns into city !== null && city !== void 0 ? city : "-" (void 0 evaluates to undefined in JavaScript), while with "es2022" it stays as it is.
module
module is the form in which tsc writes import and export. The value "nodenext" means "the way Node.js will read them".
strict
strict turns on strict mode. Since TypeScript 6.0 it is on even without this line, but it is written so that the rule is visible in the file. Strict mode is a group of checks, and each has its own name:
strictNullChecks:nullandundefinedare separate types, andnullcannot go into a variable of typestring;noImplicitAny: a parameter without a type is errorTS7006instead of silently getting the typeany.
One check can be turned off without touching the others: "noImplicitAny": false next to "strict": true. In this course every strict-mode check is on.
rootDir and outDir
rootDir is the folder with the sources, and outDir is the folder where tsc writes the JavaScript. src/main.ts becomes dist/main.js. When tsconfig.json sets outDir and the sources sit in a subfolder, TypeScript 7 requires you to name it in rootDir. Without that line it stops:
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 forbids writing JavaScript while the code has errors. It is the same --noEmitOnError flag, only written once for the whole project.
include
include is the list of folders and files tsc checks. ["src"] means "every .ts file in the src folder and in the folders inside it".
An interview question
Interviewers often ask what tsconfig.json is and what strict does. The answer: it is the file with the tsc settings for the whole project, and strict turns on a group of strict checks, among them strictNullChecks and noImplicitAny.
When tsc reads the rules
Here the picture of rules on the wall stops working. The house rules apply to everyone who walks in. tsc reads tsconfig.json only when it is run without file names.
Common mistake
Running tsc with a file name out of habit, in a folder that has a tsconfig.json:
$ 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.With a file name tsc does not read tsconfig.json, and the file would be checked with the default settings rather than by the project's rules. TypeScript 7 does not let this mistake pass silently and stops with this message.
Run tsc without file names. If you need to check one file without the project's rules, add the flag from the message: tsc --ignoreConfig src/main.ts. Then main.js appears next to main.ts rather than in dist.
Key points
tsconfig.jsonholds thetscrules for the project: the settings incompilerOptionsand the list of files ininclude.tscwithout file names readstsconfig.jsonand compiles the whole project.strictturns on a group of checks, among themstrictNullChecksandnoImplicitAny; since TypeScript 6.0 it is on by default.- When a
tsconfig.jsonis next to it,tscwith a file name stops with errorTS5112in TypeScript 7.