Open-Source Wikis

/

TypeScript

/

Primitives

/

Diagnostic

microsoft/TypeScript

Diagnostic

A single user-visible message emitted by the compiler or language service. Every error, warning, suggestion, and informational message is a Diagnostic.

Definition

In src/compiler/types.ts:

export interface Diagnostic extends DiagnosticRelatedInformation {
  reportsUnnecessary?: {};
  reportsDeprecated?: {};
  source?: string;
  relatedInformation?: DiagnosticRelatedInformation[];
  /* @internal */ skippedOn?: keyof CompilerOptions;
  /* @internal */ canonicalHead?: CanonicalDiagnostic;
}

export interface DiagnosticRelatedInformation {
  category: DiagnosticCategory;
  code: number;
  file: SourceFile | undefined;
  start: number | undefined;
  length: number | undefined;
  messageText: string | DiagnosticMessageChain;
}

export interface DiagnosticWithLocation extends Diagnostic {
  file: SourceFile;
  start: number;
  length: number;
}

export interface DiagnosticMessageChain {
  messageText: string;
  category: DiagnosticCategory;
  code: number;
  next?: DiagnosticMessageChain[];
}

DiagnosticCategory: Error, Warning, Suggestion, Message.

How a diagnostic is produced

error(node, Diagnostics.Cannot_find_name_0, name);

error(...) lives in src/compiler/utilities.ts and creates a Diagnostic keyed off:

  • The diagnostic message constant (a DiagnosticMessage from Diagnostics.* in the generated diagnosticInformationMap.generated.ts).
  • The node, which provides file, start, length.
  • Format arguments substituted into the message text.

The result is appended to the appropriate diagnostic stream:

  • SourceFile.parseDiagnostics — parser
  • SourceFile.bindDiagnostics — binder
  • Per-program semantic diagnostics — checker
  • Per-program declaration diagnostics — declaration emit
  • Service-only suggestion diagnostics — checker (with errorOrSuggestion(true, …))

Codes and messages

Every diagnostic has a stable numeric code (e.g., 2304: Cannot find name '{0}'.). Codes are assigned manually in diagnosticMessages.json and never reused. The ranges tell you what category a diagnostic comes from:

Range Origin
1xxx Parser
2xxx Checker (semantic)
4xxx Declaration emit
5xxx Compiler options / config
6xxx Build mode / watch mode
7xxx Implicit-any / --noImplicitAny
9xxx Internal compiler errors
17xxx JSX
18xxx JSDoc-related

Chained diagnostics

A type error like:

Type '{ a: number; }' is not assignable to type '{ a: string; b: number; }'.
  Types of property 'a' are incompatible.
    Type 'number' is not assignable to type 'string'.

is one Diagnostic whose messageText is a DiagnosticMessageChain linked-list. The chain is built by chainDiagnosticMessages(...) as the structural-comparison logic descends. The formatter walks the chain and indents each level.

Diagnostic.relatedInformation is an array of DiagnosticRelatedInformation, each pointing to a different file/range. The formatter prints these as additional context lines:

foo.ts(3,5): error TS2300: Duplicate identifier 'x'.
  bar.ts(7,9): 'x' was also declared here.

Filtering

SourceFile.commentDirectives (set by the parser when it sees // @ts-ignore, // @ts-expect-error, // @ts-nocheck) is consulted at diagnostic-output time. The filter lives in src/compiler/programDiagnostics.ts. @ts-expect-error reports a new diagnostic if the suppressed line had no diagnostic to suppress.

Output

tsc formats diagnostics for the terminal:

  • formatDiagnostic(diagnostic, host) — single line: path/file.ts(12,5): error TS2304: Cannot find name 'foo'.
  • formatDiagnosticsWithColorAndContext(diagnostics, host) — multi-line, with source-context excerpts and ANSI colours.

tsserver returns the raw Diagnostic shape (with start/length already converted into line/column for the protocol).

The language service additionally returns unrecoverableErrorAttempt: SignatureHelp and similar when entries belong to specific feature contexts.

Tests

Compiler tests produce a .errors.txt baseline containing the formatted error output. A change that affects diagnostic ordering, wording, or position is immediately visible in the diff.

Integration points

  • Parser, binder, checker, language service all produce diagnostics.
  • Program.getSyntacticDiagnostics, getSemanticDiagnostics, getDeclarationDiagnostics, getOptionsDiagnostics, getGlobalDiagnostics are the public consumption surfaces.
  • Code fixes are registered against diagnostic codes (src/services/codefixes/).

See also

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

Diagnostic – TypeScript wiki | Factory