0
# Configuration Management
1
2
TSLint provides comprehensive configuration management with support for multiple file formats, inheritance, and programmatic configuration loading.
3
4
## Configuration Loading
5
6
### Finding Configuration
7
8
```typescript { .api }
9
import { Configuration } from 'tslint';
10
11
// Find configuration relative to a file
12
function findConfiguration(
13
configFile: string | null,
14
inputFilePath: string
15
): IConfigurationLoadResult
16
17
// Find configuration file path
18
function findConfigurationPath(
19
suppliedConfigFilePath: string | null,
20
inputFilePath: string
21
): string | undefined
22
```
23
24
```typescript { .api }
25
interface IConfigurationLoadResult {
26
path?: string;
27
results?: IConfigurationFile;
28
}
29
```
30
31
**Example:**
32
```typescript
33
import { Configuration } from 'tslint';
34
35
// Find configuration for a specific file
36
const configResult = Configuration.findConfiguration(
37
'./tslint.json', // Config file path or undefined for auto-discovery
38
'./src/components/App.tsx' // File being linted
39
);
40
41
if (configResult.results) {
42
console.log(`Configuration loaded from: ${configResult.path}`);
43
console.log(`Rules defined: ${configResult.results.rules.size}`);
44
} else {
45
console.log('No configuration found, using defaults');
46
}
47
```
48
49
### Loading from Path
50
51
```typescript { .api }
52
// Load configuration from specific path
53
function loadConfigurationFromPath(configFilePath: string): IConfigurationLoadResult
54
```
55
56
**Example:**
57
```typescript
58
// Load specific configuration file
59
const config = Configuration.loadConfigurationFromPath('./custom-tslint.json');
60
61
if (config.results) {
62
// Use the configuration for linting
63
linter.lint(fileName, source, config.results);
64
}
65
```
66
67
## Configuration File Structure
68
69
### Core Interface
70
71
```typescript { .api }
72
interface IConfigurationFile {
73
extends: string[];
74
jsRules: Map<string, Partial<IOptions>>;
75
linterOptions?: {
76
exclude: string[];
77
format: string;
78
};
79
rulesDirectory: string[];
80
rules: Map<string, Partial<IOptions>>;
81
}
82
```
83
84
### Rule Options
85
86
```typescript { .api }
87
interface IOptions {
88
ruleArguments: any[];
89
ruleSeverity: "warning" | "error" | "off";
90
ruleName: string;
91
disabledIntervals: IDisabledInterval[];
92
}
93
```
94
95
```typescript { .api }
96
type RawRuleConfig = null | undefined | boolean | any[] | {
97
severity?: RuleSeverity | "warn" | "none" | "default";
98
options?: any;
99
};
100
101
type RuleSeverity = "warning" | "error" | "off";
102
```
103
104
## Configuration File Formats
105
106
TSLint supports multiple configuration file formats:
107
108
### JSON Format (tslint.json)
109
110
```json
111
{
112
"extends": ["tslint:recommended"],
113
"rulesDirectory": ["./custom-rules"],
114
"rules": {
115
"no-console": "error",
116
"quotemark": [true, "single"],
117
"max-line-length": {
118
"options": [120]
119
}
120
},
121
"jsRules": {
122
"no-console": "warning"
123
},
124
"linterOptions": {
125
"exclude": ["node_modules/**", "dist/**"],
126
"format": "stylish"
127
}
128
}
129
```
130
131
### YAML Format (tslint.yaml)
132
133
```yaml
134
extends:
135
- tslint:recommended
136
rulesDirectory:
137
- ./custom-rules
138
rules:
139
no-console: error
140
quotemark:
141
- true
142
- single
143
max-line-length:
144
options: [120]
145
jsRules:
146
no-console: warning
147
linterOptions:
148
exclude:
149
- "node_modules/**"
150
- "dist/**"
151
format: stylish
152
```
153
154
### JavaScript Format (tslint.js)
155
156
```javascript
157
module.exports = {
158
extends: ['tslint:recommended'],
159
rulesDirectory: ['./custom-rules'],
160
rules: {
161
'no-console': 'error',
162
'quotemark': [true, 'single'],
163
'max-line-length': { options: [120] }
164
},
165
jsRules: {
166
'no-console': 'warning'
167
},
168
linterOptions: {
169
exclude: ['node_modules/**', 'dist/**'],
170
format: 'stylish'
171
}
172
};
173
```
174
175
## Configuration Constants
176
177
```typescript { .api }
178
// Configuration file names (in order of precedence)
179
const CONFIG_FILENAMES = ["tslint.json", "tslint.yaml", "tslint.yml"];
180
const JSON_CONFIG_FILENAME = "tslint.json";
181
182
// Default configurations
183
const DEFAULT_CONFIG: IConfigurationFile;
184
const EMPTY_CONFIG: IConfigurationFile;
185
```
186
187
## Configuration Processing
188
189
### Reading Configuration Files
190
191
```typescript { .api }
192
// Read and parse configuration file
193
function readConfigurationFile(filepath: string): RawConfigFile
194
```
195
196
**Example:**
197
```typescript
198
import { Configuration } from 'tslint';
199
200
// Read raw configuration
201
const rawConfig = Configuration.readConfigurationFile('./tslint.json');
202
console.log('Raw configuration:', rawConfig);
203
204
// Parse into normalized format
205
const parsedConfig = Configuration.parseConfigFile(
206
rawConfig,
207
'./project-root',
208
Configuration.readConfigurationFile
209
);
210
```
211
212
### Parsing Configuration
213
214
```typescript { .api }
215
function parseConfigFile(
216
configFile: RawConfigFile,
217
configFileDir: string,
218
readConfig: (path: string) => RawConfigFile
219
): IConfigurationFile
220
```
221
222
```typescript { .api }
223
interface RawConfigFile {
224
extends?: string | string[];
225
linterOptions?: IConfigurationFile["linterOptions"];
226
rulesDirectory?: string | string[];
227
defaultSeverity?: string;
228
rules?: RawRulesConfig;
229
jsRules?: RawRulesConfig | boolean;
230
}
231
232
type RawRulesConfig = { [ruleName: string]: RawRuleConfig };
233
```
234
235
### Converting Rule Options
236
237
```typescript { .api }
238
// Convert raw rule configuration to normalized options
239
function convertRuleOptions(ruleConfiguration: Map<string, RawRuleConfig>): IOptions[]
240
```
241
242
## Configuration Inheritance
243
244
### Extending Configurations
245
246
```typescript { .api }
247
// Extend one configuration with another
248
function extendConfigurationFile(
249
targetConfig: IConfigurationFile,
250
nextConfigSource: IConfigurationFile
251
): IConfigurationFile
252
```
253
254
**Example:**
255
```typescript
256
import { Configuration } from 'tslint';
257
258
// Load base configuration
259
const baseConfig = Configuration.loadConfigurationFromPath('./base-tslint.json');
260
const projectConfig = Configuration.loadConfigurationFromPath('./tslint.json');
261
262
if (baseConfig.results && projectConfig.results) {
263
// Merge configurations (project config overrides base)
264
const mergedConfig = Configuration.extendConfigurationFile(
265
baseConfig.results,
266
projectConfig.results
267
);
268
}
269
```
270
271
### Built-in Configuration Presets
272
273
Common preset configurations that can be extended:
274
275
```json
276
{
277
"extends": [
278
"tslint:recommended",
279
"tslint:latest",
280
"tslint:all"
281
]
282
}
283
```
284
285
**Available Presets:**
286
- `tslint:recommended` - Recommended rules for most projects
287
- `tslint:latest` - Latest recommended rules
288
- `tslint:all` - All available rules (very strict)
289
290
## Rules Directory Management
291
292
### Resolving Rules Directories
293
294
```typescript { .api }
295
// Get resolved rules directories
296
function getRulesDirectories(
297
directories: string | string[] | undefined,
298
relativeTo: string
299
): string[]
300
```
301
302
**Example:**
303
```typescript
304
import { Configuration } from 'tslint';
305
306
// Resolve rules directories relative to config file
307
const rulesDirs = Configuration.getRulesDirectories(
308
['./custom-rules', '../shared-rules'],
309
'/project/root'
310
);
311
312
console.log('Resolved rules directories:', rulesDirs);
313
// Output: ['/project/root/custom-rules', '/project/shared-rules']
314
```
315
316
## File Exclusion
317
318
### Checking File Exclusion
319
320
```typescript { .api }
321
// Check if file should be excluded from linting
322
function isFileExcluded(filepath: string, configFile: IConfigurationFile): boolean
323
```
324
325
**Example:**
326
```typescript
327
import { Configuration } from 'tslint';
328
329
const config = Configuration.loadConfigurationFromPath('./tslint.json').results;
330
331
if (config) {
332
const shouldSkip = Configuration.isFileExcluded('./node_modules/lib.ts', config);
333
console.log('File excluded:', shouldSkip); // true if in exclude patterns
334
}
335
```
336
337
## Configuration Serialization
338
339
### Stringifying Configuration
340
341
```typescript { .api }
342
// Convert configuration to JSON string
343
function stringifyConfiguration(configFile: IConfigurationFile): string
344
```
345
346
**Example:**
347
```typescript
348
import { Configuration } from 'tslint';
349
350
const config = Configuration.loadConfigurationFromPath('./tslint.json').results;
351
352
if (config) {
353
// Serialize configuration back to JSON
354
const jsonString = Configuration.stringifyConfiguration(config);
355
console.log('Serialized config:', jsonString);
356
357
// Save modified configuration
358
fs.writeFileSync('./modified-tslint.json', jsonString);
359
}
360
```
361
362
## Advanced Configuration Usage
363
364
### Dynamic Configuration Loading
365
366
```typescript
367
import { Configuration, IConfigurationFile } from 'tslint';
368
import * as path from 'path';
369
370
class ConfigurationManager {
371
private configCache = new Map<string, IConfigurationFile>();
372
373
loadConfig(filePath: string): IConfigurationFile | undefined {
374
const configDir = path.dirname(filePath);
375
376
// Check cache
377
if (this.configCache.has(configDir)) {
378
return this.configCache.get(configDir);
379
}
380
381
// Load configuration
382
const configResult = Configuration.findConfiguration(undefined, filePath);
383
384
if (configResult.results) {
385
this.configCache.set(configDir, configResult.results);
386
return configResult.results;
387
}
388
389
return undefined;
390
}
391
392
clearCache(): void {
393
this.configCache.clear();
394
}
395
}
396
```
397
398
### Configuration Validation
399
400
```typescript
401
import { Configuration, IConfigurationFile } from 'tslint';
402
403
function validateConfiguration(config: IConfigurationFile): string[] {
404
const errors: string[] = [];
405
406
// Validate extends
407
config.extends.forEach(extend => {
408
if (!extend.startsWith('tslint:') && !fs.existsSync(extend)) {
409
errors.push(`Extended configuration not found: ${extend}`);
410
}
411
});
412
413
// Validate rules directories
414
config.rulesDirectory.forEach(dir => {
415
if (!fs.existsSync(dir)) {
416
errors.push(`Rules directory not found: ${dir}`);
417
}
418
});
419
420
// Validate rule configurations
421
config.rules.forEach((options, ruleName) => {
422
if (options.ruleSeverity && !['error', 'warning', 'off'].includes(options.ruleSeverity)) {
423
errors.push(`Invalid severity for rule ${ruleName}: ${options.ruleSeverity}`);
424
}
425
});
426
427
return errors;
428
}
429
```
430
431
### Configuration Merging Strategies
432
433
```typescript
434
import { Configuration, IConfigurationFile } from 'tslint';
435
436
function mergeConfigurations(
437
configs: IConfigurationFile[]
438
): IConfigurationFile {
439
return configs.reduce((merged, config) =>
440
Configuration.extendConfigurationFile(merged, config),
441
Configuration.EMPTY_CONFIG
442
);
443
}
444
445
// Example: Project-specific configuration hierarchy
446
function loadProjectConfig(projectPath: string): IConfigurationFile {
447
const configs: IConfigurationFile[] = [];
448
449
// 1. Load global config
450
const globalConfig = Configuration.loadConfigurationFromPath('~/.tslint.json');
451
if (globalConfig.results) {
452
configs.push(globalConfig.results);
453
}
454
455
// 2. Load team config
456
const teamConfig = Configuration.loadConfigurationFromPath('./team-tslint.json');
457
if (teamConfig.results) {
458
configs.push(teamConfig.results);
459
}
460
461
// 3. Load project config
462
const projectConfig = Configuration.loadConfigurationFromPath(
463
path.join(projectPath, 'tslint.json')
464
);
465
if (projectConfig.results) {
466
configs.push(projectConfig.results);
467
}
468
469
return mergeConfigurations(configs);
470
}
471
```
472
473
### Environment-Specific Configuration
474
475
```typescript
476
import { Configuration, IConfigurationFile } from 'tslint';
477
478
function loadEnvironmentConfig(environment: string): IConfigurationFile | undefined {
479
const configFiles = [
480
`./tslint.${environment}.json`,
481
`./configs/tslint-${environment}.json`,
482
'./tslint.json' // fallback
483
];
484
485
for (const configFile of configFiles) {
486
if (fs.existsSync(configFile)) {
487
const config = Configuration.loadConfigurationFromPath(configFile);
488
if (config.results) {
489
return config.results;
490
}
491
}
492
}
493
494
return undefined;
495
}
496
497
// Usage
498
const config = loadEnvironmentConfig(process.env.NODE_ENV || 'development');
499
```
500
501
### Configuration API Integration
502
503
```typescript
504
import { Configuration, Linter } from 'tslint';
505
import * as express from 'express';
506
507
// REST API for configuration management
508
const app = express();
509
510
app.get('/api/config/:project', (req, res) => {
511
const projectPath = req.params.project;
512
const configResult = Configuration.findConfiguration(
513
undefined,
514
path.join('./projects', projectPath, 'src/index.ts')
515
);
516
517
if (configResult.results) {
518
res.json({
519
path: configResult.path,
520
config: Configuration.stringifyConfiguration(configResult.results)
521
});
522
} else {
523
res.status(404).json({ error: 'Configuration not found' });
524
}
525
});
526
527
app.post('/api/validate-config', (req, res) => {
528
try {
529
const rawConfig = req.body;
530
const config = Configuration.parseConfigFile(
531
rawConfig,
532
'./temp',
533
Configuration.readConfigurationFile
534
);
535
536
res.json({ valid: true, config });
537
} catch (error) {
538
res.json({ valid: false, error: error.message });
539
}
540
});
541
```