CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-tslint

An extensible static analysis linter for the TypeScript language

Pending
Overview
Eval results
Files

configuration.mddocs/

Configuration Management

TSLint provides comprehensive configuration management with support for multiple file formats, inheritance, and programmatic configuration loading.

Configuration Loading

Finding Configuration

import { Configuration } from 'tslint';

// Find configuration relative to a file
function findConfiguration(
    configFile: string | null, 
    inputFilePath: string
): IConfigurationLoadResult

// Find configuration file path  
function findConfigurationPath(
    suppliedConfigFilePath: string | null, 
    inputFilePath: string
): string | undefined
interface IConfigurationLoadResult {
    path?: string;
    results?: IConfigurationFile;
}

Example:

import { Configuration } from 'tslint';

// Find configuration for a specific file
const configResult = Configuration.findConfiguration(
    './tslint.json',           // Config file path or undefined for auto-discovery
    './src/components/App.tsx'  // File being linted
);

if (configResult.results) {
    console.log(`Configuration loaded from: ${configResult.path}`);
    console.log(`Rules defined: ${configResult.results.rules.size}`);
} else {
    console.log('No configuration found, using defaults');
}

Loading from Path

// Load configuration from specific path
function loadConfigurationFromPath(configFilePath: string): IConfigurationLoadResult

Example:

// Load specific configuration file
const config = Configuration.loadConfigurationFromPath('./custom-tslint.json');

if (config.results) {
    // Use the configuration for linting
    linter.lint(fileName, source, config.results);
}

Configuration File Structure

Core Interface

interface IConfigurationFile {
    extends: string[];
    jsRules: Map<string, Partial<IOptions>>;
    linterOptions?: {
        exclude: string[];
        format: string;
    };
    rulesDirectory: string[];
    rules: Map<string, Partial<IOptions>>;
}

Rule Options

interface IOptions {
    ruleArguments: any[];
    ruleSeverity: "warning" | "error" | "off";
    ruleName: string;
    disabledIntervals: IDisabledInterval[];
}
type RawRuleConfig = null | undefined | boolean | any[] | {
    severity?: RuleSeverity | "warn" | "none" | "default";
    options?: any;
};

type RuleSeverity = "warning" | "error" | "off";

Configuration File Formats

TSLint supports multiple configuration file formats:

JSON Format (tslint.json)

{
    "extends": ["tslint:recommended"],
    "rulesDirectory": ["./custom-rules"],
    "rules": {
        "no-console": "error",
        "quotemark": [true, "single"],
        "max-line-length": {
            "options": [120]
        }
    },
    "jsRules": {
        "no-console": "warning"
    },
    "linterOptions": {
        "exclude": ["node_modules/**", "dist/**"],
        "format": "stylish"
    }
}

YAML Format (tslint.yaml)

extends:
  - tslint:recommended
rulesDirectory:
  - ./custom-rules
rules:
  no-console: error
  quotemark: 
    - true
    - single
  max-line-length:
    options: [120]
jsRules:
  no-console: warning
linterOptions:
  exclude:
    - "node_modules/**"
    - "dist/**"
  format: stylish

JavaScript Format (tslint.js)

module.exports = {
    extends: ['tslint:recommended'],
    rulesDirectory: ['./custom-rules'],
    rules: {
        'no-console': 'error',
        'quotemark': [true, 'single'],
        'max-line-length': { options: [120] }
    },
    jsRules: {
        'no-console': 'warning'
    },
    linterOptions: {
        exclude: ['node_modules/**', 'dist/**'],
        format: 'stylish'
    }
};

Configuration Constants

// Configuration file names (in order of precedence)
const CONFIG_FILENAMES = ["tslint.json", "tslint.yaml", "tslint.yml"];
const JSON_CONFIG_FILENAME = "tslint.json";

// Default configurations
const DEFAULT_CONFIG: IConfigurationFile;
const EMPTY_CONFIG: IConfigurationFile;

Configuration Processing

Reading Configuration Files

// Read and parse configuration file
function readConfigurationFile(filepath: string): RawConfigFile

Example:

import { Configuration } from 'tslint';

// Read raw configuration
const rawConfig = Configuration.readConfigurationFile('./tslint.json');
console.log('Raw configuration:', rawConfig);

// Parse into normalized format
const parsedConfig = Configuration.parseConfigFile(
    rawConfig,
    './project-root',
    Configuration.readConfigurationFile
);

Parsing Configuration

function parseConfigFile(
    configFile: RawConfigFile,
    configFileDir: string,
    readConfig: (path: string) => RawConfigFile
): IConfigurationFile
interface RawConfigFile {
    extends?: string | string[];
    linterOptions?: IConfigurationFile["linterOptions"];
    rulesDirectory?: string | string[];
    defaultSeverity?: string;
    rules?: RawRulesConfig;
    jsRules?: RawRulesConfig | boolean;
}

type RawRulesConfig = { [ruleName: string]: RawRuleConfig };

Converting Rule Options

// Convert raw rule configuration to normalized options
function convertRuleOptions(ruleConfiguration: Map<string, RawRuleConfig>): IOptions[]

Configuration Inheritance

Extending Configurations

// Extend one configuration with another
function extendConfigurationFile(
    targetConfig: IConfigurationFile,
    nextConfigSource: IConfigurationFile
): IConfigurationFile

Example:

import { Configuration } from 'tslint';

// Load base configuration
const baseConfig = Configuration.loadConfigurationFromPath('./base-tslint.json');
const projectConfig = Configuration.loadConfigurationFromPath('./tslint.json');

if (baseConfig.results && projectConfig.results) {
    // Merge configurations (project config overrides base)
    const mergedConfig = Configuration.extendConfigurationFile(
        baseConfig.results,
        projectConfig.results
    );
}

Built-in Configuration Presets

Common preset configurations that can be extended:

{
    "extends": [
        "tslint:recommended",
        "tslint:latest",
        "tslint:all"
    ]
}

Available Presets:

  • tslint:recommended - Recommended rules for most projects
  • tslint:latest - Latest recommended rules
  • tslint:all - All available rules (very strict)

Rules Directory Management

Resolving Rules Directories

// Get resolved rules directories
function getRulesDirectories(
    directories: string | string[] | undefined,
    relativeTo: string
): string[]

Example:

import { Configuration } from 'tslint';

// Resolve rules directories relative to config file
const rulesDirs = Configuration.getRulesDirectories(
    ['./custom-rules', '../shared-rules'],
    '/project/root'
);

console.log('Resolved rules directories:', rulesDirs);
// Output: ['/project/root/custom-rules', '/project/shared-rules']

File Exclusion

Checking File Exclusion

// Check if file should be excluded from linting
function isFileExcluded(filepath: string, configFile: IConfigurationFile): boolean

Example:

import { Configuration } from 'tslint';

const config = Configuration.loadConfigurationFromPath('./tslint.json').results;

if (config) {
    const shouldSkip = Configuration.isFileExcluded('./node_modules/lib.ts', config);
    console.log('File excluded:', shouldSkip); // true if in exclude patterns
}

Configuration Serialization

Stringifying Configuration

// Convert configuration to JSON string
function stringifyConfiguration(configFile: IConfigurationFile): string

Example:

import { Configuration } from 'tslint';

const config = Configuration.loadConfigurationFromPath('./tslint.json').results;

if (config) {
    // Serialize configuration back to JSON
    const jsonString = Configuration.stringifyConfiguration(config);
    console.log('Serialized config:', jsonString);
    
    // Save modified configuration
    fs.writeFileSync('./modified-tslint.json', jsonString);
}

Advanced Configuration Usage

Dynamic Configuration Loading

import { Configuration, IConfigurationFile } from 'tslint';
import * as path from 'path';

class ConfigurationManager {
    private configCache = new Map<string, IConfigurationFile>();
    
    loadConfig(filePath: string): IConfigurationFile | undefined {
        const configDir = path.dirname(filePath);
        
        // Check cache
        if (this.configCache.has(configDir)) {
            return this.configCache.get(configDir);
        }
        
        // Load configuration
        const configResult = Configuration.findConfiguration(undefined, filePath);
        
        if (configResult.results) {
            this.configCache.set(configDir, configResult.results);
            return configResult.results;
        }
        
        return undefined;
    }
    
    clearCache(): void {
        this.configCache.clear();
    }
}

Configuration Validation

import { Configuration, IConfigurationFile } from 'tslint';

function validateConfiguration(config: IConfigurationFile): string[] {
    const errors: string[] = [];
    
    // Validate extends
    config.extends.forEach(extend => {
        if (!extend.startsWith('tslint:') && !fs.existsSync(extend)) {
            errors.push(`Extended configuration not found: ${extend}`);
        }
    });
    
    // Validate rules directories
    config.rulesDirectory.forEach(dir => {
        if (!fs.existsSync(dir)) {
            errors.push(`Rules directory not found: ${dir}`);
        }
    });
    
    // Validate rule configurations
    config.rules.forEach((options, ruleName) => {
        if (options.ruleSeverity && !['error', 'warning', 'off'].includes(options.ruleSeverity)) {
            errors.push(`Invalid severity for rule ${ruleName}: ${options.ruleSeverity}`);
        }
    });
    
    return errors;
}

Configuration Merging Strategies

import { Configuration, IConfigurationFile } from 'tslint';

function mergeConfigurations(
    configs: IConfigurationFile[]
): IConfigurationFile {
    return configs.reduce((merged, config) => 
        Configuration.extendConfigurationFile(merged, config),
        Configuration.EMPTY_CONFIG
    );
}

// Example: Project-specific configuration hierarchy
function loadProjectConfig(projectPath: string): IConfigurationFile {
    const configs: IConfigurationFile[] = [];
    
    // 1. Load global config
    const globalConfig = Configuration.loadConfigurationFromPath('~/.tslint.json');
    if (globalConfig.results) {
        configs.push(globalConfig.results);
    }
    
    // 2. Load team config
    const teamConfig = Configuration.loadConfigurationFromPath('./team-tslint.json');
    if (teamConfig.results) {
        configs.push(teamConfig.results);
    }
    
    // 3. Load project config
    const projectConfig = Configuration.loadConfigurationFromPath(
        path.join(projectPath, 'tslint.json')
    );
    if (projectConfig.results) {
        configs.push(projectConfig.results);
    }
    
    return mergeConfigurations(configs);
}

Environment-Specific Configuration

import { Configuration, IConfigurationFile } from 'tslint';

function loadEnvironmentConfig(environment: string): IConfigurationFile | undefined {
    const configFiles = [
        `./tslint.${environment}.json`,
        `./configs/tslint-${environment}.json`,
        './tslint.json' // fallback
    ];
    
    for (const configFile of configFiles) {
        if (fs.existsSync(configFile)) {
            const config = Configuration.loadConfigurationFromPath(configFile);
            if (config.results) {
                return config.results;
            }
        }
    }
    
    return undefined;
}

// Usage
const config = loadEnvironmentConfig(process.env.NODE_ENV || 'development');

Configuration API Integration

import { Configuration, Linter } from 'tslint';
import * as express from 'express';

// REST API for configuration management
const app = express();

app.get('/api/config/:project', (req, res) => {
    const projectPath = req.params.project;
    const configResult = Configuration.findConfiguration(
        undefined,
        path.join('./projects', projectPath, 'src/index.ts')
    );
    
    if (configResult.results) {
        res.json({
            path: configResult.path,
            config: Configuration.stringifyConfiguration(configResult.results)
        });
    } else {
        res.status(404).json({ error: 'Configuration not found' });
    }
});

app.post('/api/validate-config', (req, res) => {
    try {
        const rawConfig = req.body;
        const config = Configuration.parseConfigFile(
            rawConfig,
            './temp',
            Configuration.readConfigurationFile
        );
        
        res.json({ valid: true, config });
    } catch (error) {
        res.json({ valid: false, error: error.message });
    }
});

Install with Tessl CLI

npx tessl i tessl/npm-tslint

docs

cli.md

configuration.md

formatters.md

index.md

linting.md

rules.md

testing.md

tile.json