Open-Source Wikis

/

TypeScript

/

Systems

/

Command line and config

microsoft/TypeScript

Command line and config

How TypeScript turns tsc --strict --target es2020 src/index.ts and tsconfig.json into a ParsedCommandLine consumed by the rest of the compiler.

Purpose

Two related problems:

  1. CLI argument parsing. tsc accepts ~120 options, several with structured values (e.g., --lib es2020,dom, --paths). Each option needs validation, defaulting, deprecation handling, and locale-aware error messages.
  2. tsconfig.json parsing. Configuration files are JSON-with-comments (JSON-C). They support extends (single or multiple), references (project references), files, include, exclude, glob expansion, compilerOptions (typed), typeAcquisition, and watchOptions. Errors must point at the right span in the source file for editor squiggles.

Source

File Lines Role
src/compiler/commandLineParser.ts 4,300 Option declarations, JSON-C parser, glob expansion, project-reference graph
src/compiler/executeCommandLine.ts 1,500+ tsc CLI dispatcher; invokes parseCommandLine and parseJsonConfigFileContent

Key abstractions

Symbol File Role
optionDeclarations commandLineParser.ts Master table of every CLI/config option
optionsAffectingProgramStructure commandLineParser.ts Subset that requires program rebuild
parseCommandLine(args) commandLineParser.ts CLI args → ParsedCommandLine
parseJsonConfigFileContent(json, host, basePath, ...) commandLineParser.ts tsconfig.jsonParsedCommandLine
getParsedCommandLineOfConfigFile commandLineParser.ts Parses a tsconfig.json from disk with full diagnostics
convertToObject commandLineParser.ts JSON-C AST → JS object
executeCommandLine executeCommandLine.ts The whole tsc CLI

optionDeclarations is the single source of truth for every option. Each entry has:

  • name (and optional shortName)
  • type ("boolean", "number", "string", "list", or a typed enum map)
  • category (used by --help grouping)
  • description (a Diagnostics key — these messages are localised)
  • defaultValueDescription (shown in --help)
  • affectsProgramStructure / affectsBindDiagnostics / affectsSemanticDiagnostics / affectsEmit / affectsModuleResolution flags — the rest of the compiler uses these to decide whether to rebuild what when an option changes.

How it works

graph LR
    CLI["argv from sys.args"] --> PCL["parseCommandLine"]
    PCL -->|may include --project| FCF["findConfigFile"]
    FCF --> RJSON["readJsonConfigFile"]
    RJSON --> PJSON["parseJsonText (JSON-C parser)"]
    PJSON --> PJCF["parseJsonConfigFileContent"]
    PJCF --> EXTENDS["extends chain resolution"]
    PJCF --> GLOBS["glob expansion (files/include/exclude)"]
    PJCF --> REFS["project references"]
    PJCF --> CO["typed compilerOptions"]
    CO --> Validate["validateCompilerOptions"]
    Validate --> PCL2["ParsedCommandLine"]
    PCL2 --> Program["createProgram"]

The extends resolution walks parent configs (which may themselves extend further), validates that each path resolves, and merges options leaf-first. extends can take a string or string array.

Glob expansion in commandLineParser.ts handles **/*.ts, character classes, brace expansion, and exclusion semantics. The result is a deterministic list of source files anchored at the config file's directory.

Project references — references: [{ path: "../shared" }] — are resolved transitively. The result is a DAG of ResolvedProjectReference records that tsbuildPublic.ts later orders into a build plan. See systems/build-mode.

Diagnostics surfacing

Errors detected during parsing are emitted as standard Diagnostics tagged with the tsconfig.json source file and a node range, so editors can underline the offending option. The convertConfigFileToObject and validateCompilerOptions paths are exhaustive — almost every kind of mistake (typo'd option, wrong type, mutually exclusive options, etc.) becomes a typed diagnostic message in src/compiler/diagnosticMessages.json.

Adding a new option

  1. Add the option declaration to optionDeclarations in src/compiler/commandLineParser.ts.
  2. Set its category and description keys; add the description message to diagnosticMessages.json and run hereby generate-diagnostics.
  3. Add a corresponding field to the CompilerOptions interface in src/compiler/types.ts.
  4. Set the appropriate affects* flag so the rest of the pipeline knows when to invalidate cached state.
  5. Implement the actual behaviour wherever it belongs (checker, emitter, transformer, etc.).
  6. Add a compiler test under tests/cases/compiler/ that exercises the new option.

Integration points

  • Read by createProgram to know which files to load and how to type-check them.
  • Read by tsbuildPublic.ts for project-reference graph building.
  • Read by executeCommandLine to decide between watch, build, and one-shot modes.
  • Re-parsed on every tsconfig.json change in watch and tsserver scenarios.

For the user-facing flags themselves, see the TypeScript handbook compiler options reference.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Command line and config – TypeScript wiki | Factory