or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli.mdconfiguration.mdformatters.mdindex.mdlinting.mdrules.mdtesting.md

linting.mddocs/

0

# Core Linting

1

2

This document covers TSLint's core linting functionality, including the Linter class, programmatic usage patterns, and integration with TypeScript programs.

3

4

## Linter Class

5

6

The `Linter` class is TSLint's primary interface for programmatic linting operations.

7

8

### Constructor

9

10

```typescript { .api }

11

class Linter {

12

constructor(options: ILinterOptions, program?: ts.Program)

13

}

14

```

15

16

```typescript { .api }

17

interface ILinterOptions {

18

fix: boolean;

19

formatter?: string | FormatterConstructor;

20

formattersDirectory?: string;

21

quiet?: boolean;

22

rulesDirectory?: string | string[];

23

}

24

```

25

26

**Parameters:**

27

- `options.fix` - Enable automatic fixing of violations

28

- `options.formatter` - Formatter name or constructor for output formatting

29

- `options.formattersDirectory` - Directory containing custom formatters

30

- `options.quiet` - Suppress warnings, only show errors

31

- `options.rulesDirectory` - Directory or directories containing custom rules

32

- `program` - Optional TypeScript program for type-aware linting

33

34

### Instance Methods

35

36

#### lint()

37

38

```typescript { .api }

39

lint(fileName: string, source: string, configuration?: IConfigurationFile): void

40

```

41

42

Lints a single file with the provided source code and configuration.

43

44

**Parameters:**

45

- `fileName` - File path for error reporting

46

- `source` - Source code to lint

47

- `configuration` - Optional linting configuration (uses default if not provided)

48

49

**Example:**

50

```typescript

51

import { Linter, Configuration } from 'tslint';

52

import * as fs from 'fs';

53

54

const linter = new Linter({ fix: false });

55

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

56

const source = fs.readFileSync('./src/example.ts', 'utf8');

57

58

linter.lint('./src/example.ts', source, config.results);

59

```

60

61

#### getResult()

62

63

```typescript { .api }

64

getResult(): LintResult

65

```

66

67

Returns the complete linting results after all files have been processed.

68

69

```typescript { .api }

70

interface LintResult {

71

errorCount: number;

72

warningCount: number;

73

failures: RuleFailure[];

74

fixes?: RuleFailure[];

75

format: string | FormatterConstructor;

76

output: string;

77

}

78

```

79

80

**Example:**

81

```typescript

82

const result = linter.getResult();

83

84

console.log(`Found ${result.errorCount} errors and ${result.warningCount} warnings`);

85

console.log('Formatted output:');

86

console.log(result.output);

87

88

// Access individual failures

89

result.failures.forEach(failure => {

90

console.log(`${failure.getFileName()}:${failure.getStartPosition().line + 1} - ${failure.getFailure()}`);

91

});

92

```

93

94

### Static Properties

95

96

```typescript { .api }

97

class Linter {

98

static VERSION: string = "6.1.3";

99

static findConfiguration: typeof Configuration.findConfiguration;

100

static findConfigurationPath: typeof Configuration.findConfigurationPath;

101

static getRulesDirectories: typeof Configuration.getRulesDirectories;

102

static loadConfigurationFromPath: typeof Configuration.loadConfigurationFromPath;

103

}

104

```

105

106

### Static Methods

107

108

#### createProgram()

109

110

```typescript { .api }

111

static createProgram(configFile: string, projectDirectory?: string): ts.Program

112

```

113

114

Creates a TypeScript program from a tsconfig.json file for type-aware linting.

115

116

**Parameters:**

117

- `configFile` - Path to tsconfig.json file

118

- `projectDirectory` - Optional project root directory

119

120

**Example:**

121

```typescript

122

// Create TypeScript program for type-aware rules

123

const program = Linter.createProgram('./tsconfig.json', './');

124

const linter = new Linter({ fix: false }, program);

125

126

// Lint files with type information

127

const fileNames = Linter.getFileNames(program);

128

fileNames.forEach(fileName => {

129

const sourceFile = program.getSourceFile(fileName);

130

if (sourceFile) {

131

linter.lint(fileName, sourceFile.getFullText(), configuration);

132

}

133

});

134

```

135

136

#### getFileNames()

137

138

```typescript { .api }

139

static getFileNames(program: ts.Program): string[]

140

```

141

142

Extracts lintable file names from a TypeScript program, excluding declaration files.

143

144

## Configuration Integration

145

146

### Loading Configuration

147

148

```typescript

149

import { Configuration, IConfigurationLoadResult } from 'tslint';

150

151

// Find configuration relative to a file

152

const configResult: IConfigurationLoadResult = Configuration.findConfiguration(

153

'./tslint.json',

154

'./src/myfile.ts'

155

);

156

157

if (configResult.results) {

158

// Use the loaded configuration

159

linter.lint('myfile.ts', source, configResult.results);

160

}

161

```

162

163

### Configuration File Structure

164

165

```typescript { .api }

166

interface IConfigurationFile {

167

extends: string[];

168

jsRules: Map<string, Partial<IOptions>>;

169

linterOptions?: {

170

exclude: string[];

171

format: string;

172

};

173

rulesDirectory: string[];

174

rules: Map<string, Partial<IOptions>>;

175

}

176

```

177

178

## Advanced Usage Patterns

179

180

### Batch Linting Multiple Files

181

182

```typescript

183

import { Linter, Configuration } from 'tslint';

184

import * as fs from 'fs';

185

import * as glob from 'glob';

186

187

function lintProject(pattern: string, configPath: string): LintResult {

188

const linter = new Linter({ fix: false, formatter: 'json' });

189

const config = Configuration.loadConfigurationFromPath(configPath);

190

191

const files = glob.sync(pattern);

192

193

files.forEach(filePath => {

194

const source = fs.readFileSync(filePath, 'utf8');

195

linter.lint(filePath, source, config.results);

196

});

197

198

return linter.getResult();

199

}

200

201

// Usage

202

const result = lintProject('./src/**/*.ts', './tslint.json');

203

console.log(`Project has ${result.errorCount} errors`);

204

```

205

206

### Type-Aware Linting with Program

207

208

```typescript

209

import { Linter, Configuration } from 'tslint';

210

import * as ts from 'typescript';

211

212

function lintWithTypeChecking(projectPath: string): LintResult {

213

// Create TypeScript program

214

const program = Linter.createProgram('./tsconfig.json', projectPath);

215

const linter = new Linter({ fix: false }, program);

216

217

// Load configuration

218

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

219

220

// Get files to lint

221

const fileNames = Linter.getFileNames(program);

222

223

fileNames.forEach(fileName => {

224

const sourceFile = program.getSourceFile(fileName);

225

if (sourceFile) {

226

linter.lint(fileName, sourceFile.getFullText(), config.results);

227

}

228

});

229

230

return linter.getResult();

231

}

232

```

233

234

### Auto-fixing with Custom Handling

235

236

```typescript

237

import { Linter, RuleFailure, Replacement } from 'tslint';

238

import * as fs from 'fs';

239

240

function lintAndFix(filePath: string, config: any): string {

241

const source = fs.readFileSync(filePath, 'utf8');

242

const linter = new Linter({ fix: true });

243

244

linter.lint(filePath, source, config);

245

const result = linter.getResult();

246

247

// Apply fixes to source code

248

if (result.fixes && result.fixes.length > 0) {

249

const fixes = result.fixes

250

.map(failure => failure.getFix())

251

.filter(fix => fix !== undefined) as Replacement[][];

252

253

const allReplacements = fixes.reduce((acc, fix) => acc.concat(fix), []);

254

return Replacement.applyAll(source, allReplacements);

255

}

256

257

return source;

258

}

259

```

260

261

### Custom Formatter Integration

262

263

```typescript

264

import { Linter, AbstractFormatter } from 'tslint';

265

266

class CustomFormatter extends AbstractFormatter {

267

public format(failures: RuleFailure[]): string {

268

return failures.map(failure =>

269

`⚠️ ${failure.getFileName()}: ${failure.getFailure()}`

270

).join('\n');

271

}

272

}

273

274

// Use custom formatter

275

const linter = new Linter({

276

fix: false,

277

formatter: CustomFormatter

278

});

279

```

280

281

## Error Handling

282

283

```typescript

284

import { Linter, Configuration } from 'tslint';

285

286

function safeLint(fileName: string, source: string): LintResult | null {

287

try {

288

const linter = new Linter({ fix: false });

289

290

// Attempt to load configuration

291

let config;

292

try {

293

config = Configuration.findConfiguration('./tslint.json', fileName).results;

294

} catch (configError) {

295

console.warn('Configuration not found, using defaults');

296

config = undefined;

297

}

298

299

linter.lint(fileName, source, config);

300

return linter.getResult();

301

302

} catch (error) {

303

console.error('Linting failed:', error.message);

304

return null;

305

}

306

}

307

```

308

309

## Performance Considerations

310

311

### Reusing TypeScript Program

312

313

```typescript

314

// Efficient for linting multiple files with type checking

315

const program = Linter.createProgram('./tsconfig.json');

316

const linter = new Linter({ fix: false }, program);

317

318

// Reuse the same linter and program for multiple files

319

Linter.getFileNames(program).forEach(fileName => {

320

const sourceFile = program.getSourceFile(fileName);

321

if (sourceFile) {

322

linter.lint(fileName, sourceFile.getFullText(), config);

323

}

324

});

325

```

326

327

### Memory Management

328

329

```typescript

330

// For large projects, process files in batches

331

function lintInBatches(files: string[], batchSize: number = 50): LintResult[] {

332

const results: LintResult[] = [];

333

334

for (let i = 0; i < files.length; i += batchSize) {

335

const batch = files.slice(i, i + batchSize);

336

const linter = new Linter({ fix: false });

337

338

batch.forEach(file => {

339

const source = fs.readFileSync(file, 'utf8');

340

linter.lint(file, source, config);

341

});

342

343

results.push(linter.getResult());

344

}

345

346

return results;

347

}

348

```

349

350

## Integration Examples

351

352

### Express.js Middleware

353

354

```typescript

355

import { Linter, Configuration } from 'tslint';

356

import * as express from 'express';

357

358

function createLintMiddleware() {

359

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

360

361

return (req: express.Request, res: express.Response, next: express.NextFunction) => {

362

if (req.body && req.body.source) {

363

const linter = new Linter({ fix: false, formatter: 'json' });

364

linter.lint('uploaded.ts', req.body.source, config.results);

365

366

req.lintResult = linter.getResult();

367

}

368

next();

369

};

370

}

371

```

372

373

### Build Tool Integration

374

375

```typescript

376

// Webpack plugin example

377

class TSLintPlugin {

378

apply(compiler: any) {

379

compiler.hooks.emit.tapAsync('TSLintPlugin', (compilation: any, callback: Function) => {

380

const linter = new Linter({ fix: false });

381

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

382

383

// Lint all TypeScript assets

384

Object.keys(compilation.assets).forEach(filename => {

385

if (filename.endsWith('.ts')) {

386

const source = compilation.assets[filename].source();

387

linter.lint(filename, source, config.results);

388

}

389

});

390

391

const result = linter.getResult();

392

if (result.errorCount > 0) {

393

compilation.errors.push(new Error('TSLint errors found'));

394

}

395

396

callback();

397

});

398

}

399

}

400

```