How to Use createDiagnosticsPlugin in tsslint to Filter and Modify TypeScript Diagnostics

The createDiagnosticsPlugin is a built-in tsslint factory function that collects TypeScript compiler diagnostics (syntactic, semantic, or declaration errors) and merges them with lint rule diagnostics, enabling unified filtering, enrichment, or transformation of the final diagnostic output.

The createDiagnosticsPlugin serves as a bridge between TypeScript's native error detection and tsslint's rule-based linting system. Implemented in packages/config/lib/plugins/diagnostics.ts and exported from @tsslint/config, this plugin implements the PluginInstance interface to intercept and augment the diagnostic stream before final reporting.

What createDiagnosticsPlugin Does

The primary purpose of createDiagnosticsPlugin is to inject TypeScript compiler diagnostics into the linting results. According to the implementation in packages/config/lib/plugins/diagnostics.ts, the plugin performs three core operations:

  • Collects TypeScript diagnostics – Retrieves diagnostics from the TypeScript program based on the specified check mode(s): 'syntactic', 'semantic', or 'declaration'.
  • Merges with lint diagnostics – Appends the collected TypeScript diagnostics to the array of diagnostics produced by tsslint rules.
  • Normalizes missing fields – Ensures every diagnostic has defined start and length properties, defaulting to 0 if undefined, preventing downstream errors in formatters or other plugins.

How createDiagnosticsPlugin Fits into the Architecture

Understanding the plugin's position in tsslint's execution flow clarifies how to leverage it effectively for filtering and modification.

Plugin Interface Implementation

All tsslint plugins implement the PluginInstance interface defined in packages/types/index.ts. The relevant hook is the optional resolveDiagnostics? method:

// packages/types/index.ts
interface PluginInstance {
  resolveDiagnostics?(fileName: string, diagnostics: Diagnostic[]): Diagnostic[];
  // ... other methods
}

The createDiagnosticsPlugin returns an object implementing this interface, specifically providing the resolveDiagnostics function that modifies the diagnostics array.

Core Runner Integration

The tsslint core runner invokes plugin hooks in packages/core/index.ts (lines 167-173). After executing lint rules, the runner calls each plugin's resolveDiagnostics method in sequence, passing the accumulated diagnostics array. This allows createDiagnosticsPlugin to augment the diagnostics before they reach the formatter or output stage.

Export Location

The factory function is exported from packages/config/index.ts as createDiagnosticsPlugin, making it available via the @tsslint/config package:

// packages/config/index.ts
export { createDiagnosticsPlugin } from './lib/plugins/diagnostics';

Configuration and Usage Examples

Basic Usage: Adding Semantic Diagnostics

By default, createDiagnosticsPlugin() collects semantic diagnostics from TypeScript. This is the most common use case for catching type errors alongside lint violations.

// tsslint.config.ts
import { defineConfig, createDiagnosticsPlugin } from '@tsslint/config';
import NoConsoleRule from './noConsoleRule';

export default defineConfig({
  rules: {
    'no-console': NoConsoleRule,
  },
  plugins: [
    // Inject TypeScript semantic diagnostics into the lint report
    createDiagnosticsPlugin(),
  ],
});

The factory signature confirms this default: create(mode: CheckMode | CheckMode[] = 'semantic').

Requesting Multiple Diagnostic Kinds

To capture syntactic errors (parse errors) alongside semantic ones, pass an array of check modes:

// tsslint.config.ts
import { defineConfig, createDiagnosticsPlugin } from '@tsslint/config';

export default defineConfig({
  plugins: [
    // Collect both syntactic and semantic diagnostics
    createDiagnosticsPlugin(['syntactic', 'semantic']),
  ],
});

Available modes include:

  • 'syntactic' – Parse errors and malformed syntax
  • 'semantic' – Type checking errors
  • 'declaration' – Errors in declaration files (.d.ts)

Chaining with Diagnostic Filter Plugins

Because tsslint processes plugins sequentially, you can chain createDiagnosticsPlugin with other plugins to filter or modify the merged output. For example, combining with an ignore plugin:

// tsslint.config.ts
import { defineConfig, createDiagnosticsPlugin, createIgnorePlugin } from '@tsslint/config';

export default defineConfig({
  plugins: [
    // First: Add TypeScript diagnostics to the array
    createDiagnosticsPlugin(),
    // Then: Remove diagnostics on lines containing // @tsslint-ignore
    createIgnorePlugin(/\/\/ @tsslint-ignore/g),
  ],
});

The order matters: the ignore plugin receives the augmented diagnostics array including the TypeScript compiler errors, allowing it to filter both rule violations and compiler diagnostics.

Advanced: Programmatic Usage

For custom tooling or testing, you can invoke the plugin factory directly without the config file abstraction:

import { createDiagnosticsPlugin } from '@tsslint/config';
import { createProgram } from 'typescript';

// Setup TypeScript program
const program = createProgram(['src/index.ts'], {});
const sourceFile = program.getSourceFile('src/index.ts')!;

// Initial diagnostics array (possibly from other rules)
let diagnostics: ts.DiagnosticWithLocation[] = [];

// Create plugin instance with specific modes
const plugin = createDiagnosticsPlugin(['semantic', 'declaration'])({
  languageService: { getProgram: () => program } as any,
});

// Resolve diagnostics
if (plugin.resolveDiagnostics) {
  diagnostics = plugin.resolveDiagnostics(sourceFile.fileName, diagnostics);
}

This demonstrates the low-level contract: the plugin receives a languageService with a getProgram method and returns an object with a resolveDiagnostics function that transforms the array.

Summary

  • Purpose: createDiagnosticsPlugin bridges TypeScript compiler diagnostics and tsslint rule diagnostics, enabling unified error reporting.
  • Location: Implemented in packages/config/lib/plugins/diagnostics.ts and exported from packages/config/index.ts.
  • Default behavior: Collects semantic diagnostics unless configured otherwise with 'syntactic', 'semantic', or 'declaration' modes.
  • Integration: Implements the PluginInstance interface from packages/types/index.ts, specifically the resolveDiagnostics? hook called by the core runner in packages/core/index.ts.
  • Normalization: Automatically ensures all diagnostics have start and length properties set to 0 if undefined.
  • Chaining: Works sequentially with other plugins, allowing filtering or modification of the merged diagnostic array based on plugin order.

Frequently Asked Questions

What is the default diagnostic mode for createDiagnosticsPlugin?

By default, createDiagnosticsPlugin() operates in 'semantic' mode. This means it collects only semantic diagnostics from the TypeScript program (type errors), ignoring syntactic parse errors and declaration file diagnostics unless explicitly requested via the configuration array.

How does createDiagnosticsPlugin handle diagnostics without position information?

The plugin normalizes diagnostics to ensure downstream compatibility. In packages/config/lib/plugins/diagnostics.ts, the implementation checks for undefined start and length properties on each diagnostic and defaults them to 0. This prevents errors in formatters or other plugins that expect these numeric fields to be defined.

Can I use createDiagnosticsPlugin with custom tsslint rules?

Yes. The plugin is designed to merge with existing diagnostics rather than replace them. When the core runner in packages/core/index.ts invokes resolveDiagnostics, it passes the array of diagnostics already produced by your custom rules. The plugin appends TypeScript compiler diagnostics to this array, creating a unified report containing both rule violations and compiler errors.

Where should createDiagnosticsPlugin appear in the plugins array order?

Position depends on your filtering needs. If you want to filter or modify TypeScript diagnostics (for example, ignoring certain compiler errors), place createDiagnosticsPlugin before filter plugins like createIgnorePlugin. If you want to ensure your ignore rules also apply to TypeScript diagnostics, place it before the ignore plugin so the filter receives the merged array. The core runner processes plugins sequentially in packages/core/index.ts, so order determines which transformations see which diagnostics.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →