1{ "compilerOptions": {2 "target": "es2019", "target": "es2020",3 "strict": true,4 "rootDir": "src",5 "outDir": "dist" },6 "include": ["src"] }1function hi(n?) {function hi(n?: string) {2 return n ?? "you";3}4console.log(hi());not built yet1"use strict";2function hi(n) {3 return n !== null && n !== void 0 ? n : "you"; return n ?? "you";4}5console.log(hi());tsccompiler!✓jsonTSJS
Back row: tsconfig.json (the settings) and src/index.ts (the source)Front row: dist/index.js (the output) and tsc, the compilerTokens: what tsc reads (json, TS) and what it writes (JS)At the back: tsconfig.json, the project's settings, and src/index.ts, the TypeScript you write. In front: dist/index.js, where tsc writes the output, and tsc itself. With "strict": true, tsc rejects the untyped parameter n on line 1 (TS7006). After the fix it writes dist/index.js: for target es2019 it rewrites ?? into older JavaScript; for es2020 it keeps it. With file names, as in tsc src/index.ts, tsc does not use tsconfig.json; current versions stop with error TS5112 unless you add --ignoreConfig. Use tsc -p <folder> to build a project somewhere else.

The project

  1. Run tsc with no file names and it looks for tsconfig.json, first in the current folder, then in each parent folder. That file marks a project: every compiler setting in one place, so everyone builds the same way.

How strict

Which JavaScript

What happens

;; step 1/8 · project
$ tsc

looks for tsconfig.json here, then in each parent folder
tsconfig.json
  1  { "compilerOptions": {
  2      "target": "es2019",
  3      "strict": true,
  4      "rootDir": "src",
  5      "outDir": "dist" },
  6    "include": ["src"] }

with file names (tsc a.ts) tsc does not use it:
it stops with error TS5112 unless you add --ignoreConfig

Every error and every dist/index.js shown is exactly what tsc 7.0.2 writes for these files (tsc 6.0.3 writes the same). Defaults change between major versions, so set the options you rely on instead of trusting the defaults. "rootDir": "src" tells tsc where the source starts, so src/index.ts becomes dist/index.js. Since TypeScript 6.0, leaving it out here is error TS5011. tsc writes "use strict"; at the top of a script file (one with no import or export). Since TypeScript 6.0 it does so with or without "strict". By default tsc still writes the .js files when it finds type errors; set "noEmitOnError": true to stop that.