or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli.mdindex.mdprogrammatic-api.md

programmatic-api.mddocs/

0

# Programmatic API

1

2

The type-coverage-core library provides a programmatic API for integrating TypeScript type coverage analysis into custom tools, build systems, and development workflows.

3

4

## Capabilities

5

6

### Primary Analysis Functions

7

8

#### Asynchronous Type Coverage Analysis

9

10

Analyze a TypeScript project asynchronously with automatic configuration discovery.

11

12

```typescript { .api }

13

/**

14

* Analyze TypeScript project for type coverage

15

* @param project - Path to project directory or tsconfig.json file

16

* @param options - Optional configuration for analysis

17

* @returns Promise resolving to analysis results

18

*/

19

function lint(

20

project: string,

21

options?: Partial<LintOptions>

22

): Promise<LintResult>;

23

```

24

25

**Usage Examples:**

26

27

```typescript

28

import { lint } from "type-coverage-core";

29

30

// Basic analysis

31

const result = await lint("./");

32

console.log(`Coverage: ${result.correctCount}/${result.totalCount}`);

33

34

// Analysis with options

35

const result = await lint("./src", {

36

strict: true,

37

enableCache: true,

38

ignoreFiles: ["**/*.test.ts"],

39

reportSemanticError: true

40

});

41

42

// Check coverage threshold

43

const percentage = (result.correctCount / result.totalCount) * 100;

44

if (percentage < 90) {

45

throw new Error(`Coverage ${percentage.toFixed(2)}% below threshold`);

46

}

47

```

48

49

#### Synchronous Type Coverage Analysis

50

51

Analyze TypeScript files synchronously with explicit compiler configuration.

52

53

```typescript { .api }

54

/**

55

* Analyze TypeScript files synchronously with explicit configuration

56

* @param compilerOptions - TypeScript compiler options

57

* @param rootNames - Array of root file paths to analyze

58

* @param options - Optional configuration for analysis

59

* @returns Analysis results

60

*/

61

function lintSync(

62

compilerOptions: ts.CompilerOptions,

63

rootNames: string[],

64

options?: Partial<LintOptions>

65

): LintSyncResult;

66

```

67

68

**Usage Examples:**

69

70

```typescript

71

import { lintSync } from "type-coverage-core";

72

import * as ts from "typescript";

73

74

// With explicit configuration

75

const compilerOptions: ts.CompilerOptions = {

76

target: ts.ScriptTarget.ES2020,

77

module: ts.ModuleKind.CommonJS,

78

lib: ["ES2020"],

79

strict: true

80

};

81

82

const result = lintSync(compilerOptions, ["src/main.ts", "src/utils.ts"], {

83

strict: true,

84

ignoreNested: true

85

});

86

87

console.log(`Files analyzed: ${result.fileCounts?.size || 0}`);

88

```

89

90

## Types and Interfaces

91

92

### Analysis Results

93

94

```typescript { .api }

95

// Return type for lint() function

96

type LintResult = {

97

/** Number of identifiers with explicit types */

98

correctCount: number;

99

/** Total number of identifiers analyzed */

100

totalCount: number;

101

/** Array of any type issues found */

102

anys: AnyInfo[];

103

/** TypeScript program instance used for analysis */

104

program: ts.Program;

105

/** Per-file coverage statistics (when fileCounts option is true) */

106

fileCounts: Map<string, Pick<FileTypeCheckResult, 'correctCount' | 'totalCount'>>;

107

};

108

109

// Return type for lintSync() function

110

type LintSyncResult = {

111

/** Number of identifiers with explicit types */

112

correctCount: number;

113

/** Total number of identifiers analyzed */

114

totalCount: number;

115

/** Array of any type issues with source file references */

116

anys: Array<AnyInfo & { sourceFile: ts.SourceFile }>;

117

/** TypeScript program instance used for analysis */

118

program: ts.Program;

119

/** Per-file coverage statistics (when fileCounts option is true) */

120

fileCounts: Map<string, Pick<FileTypeCheckResult, 'correctCount' | 'totalCount'>>;

121

};

122

```

123

124

### Configuration Options

125

126

```typescript { .api }

127

interface LintOptions {

128

/** Enable debug output during analysis */

129

debug: boolean;

130

/** Enable strict mode checking (includes all strict options) */

131

strict: boolean;

132

/** Enable result caching for improved performance */

133

enableCache: boolean;

134

/** File patterns to ignore during analysis */

135

ignoreFiles?: string | string[];

136

/** Ignore catch clause variables */

137

ignoreCatch: boolean;

138

/** Allow writes to variables with implicit any types */

139

ignoreUnreadAnys: boolean;

140

/** Generate per-file coverage statistics */

141

fileCounts: boolean;

142

/** Use absolute file paths in results */

143

absolutePath?: boolean;

144

/** Report TypeScript semantic errors */

145

reportSemanticError: boolean;

146

/** Report unused ignore directives */

147

reportUnusedIgnore: boolean;

148

/** Custom cache directory location */

149

cacheDirectory?: string;

150

/** Include results outside current working directory */

151

notOnlyInCWD?: boolean;

152

/** Specific files to analyze (overrides project discovery) */

153

files?: string[];

154

/** Previous TypeScript program for incremental compilation */

155

oldProgram?: ts.Program;

156

/** Custom any type processor function */

157

processAny?: ProccessAny;

158

159

// Strict mode options (individually configurable)

160

/** Ignore any in type arguments (Promise<any>) */

161

ignoreNested: boolean;

162

/** Ignore as assertions (foo as string) */

163

ignoreAsAssertion: boolean;

164

/** Ignore type assertions (<string>foo) */

165

ignoreTypeAssertion: boolean;

166

/** Ignore non-null assertions (foo!) */

167

ignoreNonNullAssertion: boolean;

168

/** Don't count Object type as any */

169

ignoreObject: boolean;

170

/** Don't count empty type {} as any */

171

ignoreEmptyType: boolean;

172

}

173

```

174

175

### Issue Information

176

177

```typescript { .api }

178

interface AnyInfo {

179

/** File path where issue was found */

180

file: string;

181

/** Line number (0-based) */

182

line: number;

183

/** Character position (0-based) */

184

character: number;

185

/** Description of the issue */

186

text: string;

187

/** Category of any type issue */

188

kind: FileAnyInfoKind;

189

}

190

191

interface FileAnyInfo {

192

/** Line number (0-based) */

193

line: number;

194

/** Character position (0-based) */

195

character: number;

196

/** Description of the issue */

197

text: string;

198

/** Category of any type issue */

199

kind: FileAnyInfoKind;

200

}

201

202

enum FileAnyInfoKind {

203

/** Explicit any type */

204

any = 1,

205

/** any in type arguments (Promise<any>) */

206

containsAny = 2,

207

/** Unsafe as assertion (foo as string) */

208

unsafeAs = 3,

209

/** Unsafe type assertion (<string>foo) */

210

unsafeTypeAssertion = 4,

211

/** Unsafe non-null assertion (foo!) */

212

unsafeNonNull = 5,

213

/** TypeScript semantic error */

214

semanticError = 6,

215

/** Unused ignore directive */

216

unusedIgnore = 7

217

}

218

```

219

220

### File Analysis Results

221

222

```typescript { .api }

223

interface FileTypeCheckResult {

224

/** Number of identifiers with explicit types in this file */

225

correctCount: number;

226

/** Total number of identifiers in this file */

227

totalCount: number;

228

/** Array of any type issues in this file */

229

anys: FileAnyInfo[];

230

}

231

```

232

233

### Custom Processing

234

235

```typescript { .api }

236

/**

237

* Custom processor function for any type nodes

238

* @param node - TypeScript AST node being processed

239

* @param context - File analysis context

240

* @returns true if node should be counted as any type issue

241

*/

242

type ProccessAny = (node: ts.Node, context: FileContext) => boolean;

243

244

interface FileContext {

245

/** Current file path */

246

file: string;

247

/** TypeScript source file */

248

sourceFile: ts.SourceFile;

249

/** Type checker instance */

250

checker: ts.TypeChecker;

251

/** Current analysis results */

252

typeCheckResult: FileTypeCheckResult;

253

/** Catch clause variables (for ignoreCatch option) */

254

catchVariables: { [variable: string]: boolean };

255

/** Lines with ignore directives */

256

ignoreLines?: Set<number>;

257

/** Lines where ignore directives were used */

258

usedIgnoreLines?: Set<number>;

259

260

// Configuration options

261

debug: boolean;

262

strict: boolean;

263

ignoreCatch: boolean;

264

ignoreUnreadAnys: boolean;

265

ignoreNested: boolean;

266

ignoreAsAssertion: boolean;

267

ignoreTypeAssertion: boolean;

268

ignoreNonNullAssertion: boolean;

269

ignoreObject: boolean;

270

ignoreEmptyType: boolean;

271

processAny?: ProccessAny;

272

}

273

```

274

275

## Advanced Usage Examples

276

277

### Custom Analysis Pipeline

278

279

```typescript

280

import { lint, FileAnyInfoKind } from "type-coverage-core";

281

282

async function analyzeProject(projectPath: string) {

283

const result = await lint(projectPath, {

284

strict: true,

285

enableCache: true,

286

fileCounts: true,

287

reportSemanticError: true

288

});

289

290

// Calculate overall coverage

291

const coverage = (result.correctCount / result.totalCount) * 100;

292

293

// Group issues by type

294

const issuesByKind = result.anys.reduce((acc, issue) => {

295

const kind = FileAnyInfoKind[issue.kind];

296

acc[kind] = (acc[kind] || 0) + 1;

297

return acc;

298

}, {} as Record<string, number>);

299

300

// Analyze per-file coverage

301

const fileStats = Array.from(result.fileCounts?.entries() || [])

302

.map(([file, stats]) => ({

303

file,

304

coverage: (stats.correctCount / stats.totalCount) * 100,

305

issues: stats.anys.length

306

}))

307

.sort((a, b) => a.coverage - b.coverage);

308

309

return {

310

overall: { coverage, issues: result.anys.length },

311

byType: issuesByKind,

312

byFile: fileStats

313

};

314

}

315

```

316

317

### Integration with Build Tools

318

319

```typescript

320

import { lint } from "type-coverage-core";

321

322

async function typeCoveragePlugin(options: { threshold: number }) {

323

return {

324

name: "type-coverage",

325

async buildStart() {

326

const result = await lint("./", {

327

strict: true,

328

enableCache: true

329

});

330

331

const coverage = (result.correctCount / result.totalCount) * 100;

332

333

if (coverage < options.threshold) {

334

this.error(

335

`Type coverage ${coverage.toFixed(2)}% below threshold ${options.threshold}%`

336

);

337

}

338

339

console.log(`Type coverage: ${coverage.toFixed(2)}%`);

340

}

341

};

342

}

343

```

344

345

### Incremental Analysis

346

347

```typescript

348

import { lintSync } from "type-coverage-core";

349

import * as ts from "typescript";

350

351

class IncrementalTypeCoverage {

352

private program: ts.Program | undefined;

353

354

async analyze(compilerOptions: ts.CompilerOptions, rootNames: string[]) {

355

const result = lintSync(compilerOptions, rootNames, {

356

oldProgram: this.program,

357

enableCache: true,

358

fileCounts: true

359

});

360

361

// Store program for next incremental analysis

362

this.program = result.program;

363

364

return result;

365

}

366

}

367

```