tsconfig & Compiler Options

A tsconfig.json file is the configuration that tells the TypeScript compiler which files to include and how to check and build them — controlling strictness, the output JavaScript version, the module system, and where compiled files go.

Learn tsconfig & Compiler Options in our free TypeScript course — an interactive lesson with runnable examples, a practice exercise and a quick reference.

Part of the free TypeScript course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

tsconfig.json is the settings panel on a power tool . strict is the full set of safety guards — slower to get used to, but it stops you losing a finger. target is the speed dial: how modern the output runs. lib is which attachments the tool knows it has fitted. outDir / rootDir are the in-tray and out-tray that keep raw stock and finished parts separate. You configure the panel once per project, and every build afterward follows those rules — so the whole team gets the same checks and the same output.

This is JSON, not runnable code — it's the file tsc reads before compiling. Each option is annotated:

1. Strict Mode & strictNullChecks

Setting "strict": true flips on a bundle of checks. The flagship is strictNullChecks : null and undefined stop being assignable to every type and become values you must handle explicitly. That single change eliminates a huge share of "Cannot read property of undefined" crashes:

2. noImplicitAny

Also part of strict , noImplicitAny turns "I couldn't figure out this type, so I'll silently call it any " into an error. It forces you to annotate parameters the compiler can't infer, closing the door on values that quietly do the wrong thing at runtime:

3. target , module & lib

These three decide what your compiled output looks like. target is the JavaScript version emitted (modern syntax is kept; older targets down-level it). module is the output module system (ES modules vs CommonJS). lib is the set of built-in API type definitions the checker is allowed to assume exist:

🎯 Your Turn

Write the null/undefined guard that strictNullChecks would require before using a value. Fill in the blanks and match the expected output.

Write a config reader that never crashes on a missing key or a missing config — the kind of defensive code strictNullChecks pushes you toward. Follow the outline, run it, and match the example output.

Practice quiz

What is a tsconfig.json file?

  • A runtime config loaded by your app
  • A package manifest
  • The configuration telling the compiler which files to include and how to check/build them
  • A test runner config

Answer: The configuration telling the compiler which files to include and how to check/build them. tsconfig.json controls strictness, output JS version, module system, and file layout for tsc.

What does 'strict: true' do?

  • Enables a whole family of strict checks at once
  • Enables one check
  • Disables all checks
  • Only affects formatting

Answer: Enables a whole family of strict checks at once. It turns on strictNullChecks, noImplicitAny, strictFunctionTypes, and several more together.

What does strictNullChecks change?

  • It removes null at runtime
  • It allows null everywhere
  • It converts null to 0
  • null/undefined become separate types you must handle before use

Answer: null/undefined become separate types you must handle before use. null and undefined stop being assignable to every type, eliminating many undefined crashes.

What does noImplicitAny do?

  • Bans the any keyword entirely
  • Makes a value the compiler can't infer a type for an error
  • Adds any to everything
  • Only warns on functions

Answer: Makes a value the compiler can't infer a type for an error. It forces you to annotate values that would otherwise be silently any.

What does the 'target' option control?

  • The JavaScript language version TypeScript emits
  • The module system
  • Which files compile
  • The lib APIs

Answer: The JavaScript language version TypeScript emits. target sets the emitted JS version; older targets down-level modern syntax.

What does the 'module' option control?

  • The JS version
  • The strictness level
  • The module system of the output (ESNext, CommonJS, etc.)
  • The output folder

Answer: The module system of the output (ESNext, CommonJS, etc.). module decides whether import/export stay as ES modules or become require().

What does the 'lib' option control?

  • The output directory
  • Which built-in API type definitions the checker knows (DOM, ES2017, etc.)
  • The module system
  • The strict flags

Answer: Which built-in API type definitions the checker knows (DOM, ES2017, etc.). lib lists known APIs; e.g. DOM makes document/window typed, ES2017 adds Object.entries.

What do rootDir and outDir do?

  • Set strictness
  • Pick the target
  • Control imports
  • rootDir is where source begins; outDir is where compiled files go

Answer: rootDir is where source begins; outDir is where compiled files go. They mirror your source structure into the output folder when tsc emits files.

Why does esModuleInterop exist?

  • To speed up compilation
  • To let you write natural default imports from CommonJS modules
  • To enable strict mode
  • To freeze imports

Answer: To let you write natural default imports from CommonJS modules. It maps CommonJS module.exports cleanly so 'import React from "react"' works.

In a Vite/bundler setup, how is tsc often used?

  • To bundle the app
  • Not at all
  • With --noEmit, just for type-checking while the bundler produces output
  • To minify code

Answer: With --noEmit, just for type-checking while the bundler produces output. The bundler handles output; tsc --noEmit is run purely to type-check.