(Experimental) Utilities for working with TypeScript + ESLint together
npx @tessl/cli install tessl/npm-typescript-eslint--experimental-utils@5.62.00
# @typescript-eslint/experimental-utils
1
2
`@typescript-eslint/experimental-utils` provides utilities for working with TypeScript and ESLint together. This package is a pure re-export of `@typescript-eslint/utils` and serves as a transitional compatibility layer for existing code that imports from the experimental package name.
3
4
## Package Information
5
6
- **Package Name**: @typescript-eslint/experimental-utils
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install @typescript-eslint/experimental-utils`
10
11
## Core Imports
12
13
```typescript
14
import {
15
ASTUtils,
16
ESLintUtils,
17
TSESLint,
18
TSESTree,
19
TSESLintScope,
20
JSONSchema
21
} from "@typescript-eslint/experimental-utils";
22
```
23
24
For CommonJS:
25
26
```javascript
27
const {
28
ASTUtils,
29
ESLintUtils,
30
TSESLint,
31
TSESTree
32
} = require("@typescript-eslint/experimental-utils");
33
```
34
35
## Basic Usage
36
37
```typescript
38
import { ESLintUtils, TSESLint, ASTUtils } from "@typescript-eslint/experimental-utils";
39
40
// Create a TypeScript-aware ESLint rule
41
const rule = ESLintUtils.RuleCreator(name => `https://example.com/${name}`)({
42
name: 'my-rule',
43
meta: {
44
type: 'problem',
45
messages: {
46
error: 'Found function declaration'
47
},
48
schema: []
49
},
50
defaultOptions: [],
51
create(context: TSESLint.RuleContext<'error', []>) {
52
return {
53
FunctionDeclaration(node) {
54
if (ASTUtils.isFunction(node)) {
55
context.report({
56
node,
57
messageId: 'error'
58
});
59
}
60
}
61
};
62
}
63
});
64
65
// Test the rule
66
const ruleTester = new ESLintUtils.RuleTester({
67
parser: '@typescript-eslint/parser',
68
});
69
70
ruleTester.run('my-rule', rule, {
71
valid: ['const x = 1;'],
72
invalid: [{
73
code: 'function foo() {}',
74
errors: [{ messageId: 'error' }]
75
}]
76
});
77
```
78
79
## Migration Notice
80
81
**This package is purely a re-export of `@typescript-eslint/utils`.** You should switch to importing from the non-experimental package instead:
82
83
```diff
84
- import { RuleCreator } from '@typescript-eslint/experimental-utils';
85
+ import { RuleCreator } from '@typescript-eslint/utils';
86
```
87
88
## Architecture
89
90
The package is organized into several main modules:
91
92
- **ASTUtils**: AST manipulation and analysis utilities for TypeScript syntax trees
93
- **ESLintUtils**: Rule creation, testing, and configuration utilities for ESLint integration
94
- **TSESLint**: TypeScript-enhanced ESLint types and interfaces
95
- **TSESTree**: AST node types and parser service definitions
96
- **TSESLintScope**: Scope analysis and variable tracking utilities
97
- **JSONSchema**: JSON Schema type definitions for rule configuration
98
99
## Capabilities
100
101
### AST Utilities
102
103
Tools for manipulating and analyzing TypeScript Abstract Syntax Trees, including predicates, helpers, and pattern matching utilities.
104
105
```typescript { .api }
106
namespace ASTUtils {
107
function isNodeOfType<NodeType extends TSESTree.AST_NODE_TYPES>(
108
nodeType: NodeType
109
): (node: TSESTree.Node | null | undefined) => node is Extract<TSESTree.Node, { type: NodeType }>;
110
111
function isFunction(node: TSESTree.Node | null | undefined): node is TSESTree.FunctionLike;
112
113
const LINEBREAK_MATCHER: RegExp;
114
115
function isTokenOnSameLine(
116
left: TSESTree.Node | TSESTree.Token,
117
right: TSESTree.Node | TSESTree.Token
118
): boolean;
119
}
120
```
121
122
[AST Utilities](./ast-utils.md)
123
124
### ESLint Integration Utilities
125
126
Rule creation, testing, and configuration utilities specifically designed for TypeScript ESLint rules.
127
128
```typescript { .api }
129
namespace ESLintUtils {
130
function RuleCreator(urlCreator: (ruleName: string) => string): <
131
TOptions extends readonly unknown[],
132
TMessageIds extends string,
133
TRuleListener extends TSESLint.RuleListener = TSESLint.RuleListener
134
>(ruleDefinition: Readonly<TSESLint.RuleModule<TMessageIds, TOptions, TRuleListener>>) => TSESLint.RuleModule<TMessageIds, TOptions>;
135
136
function getParserServices<TMessageIds extends string, TOptions extends readonly unknown[]>(
137
context: TSESLint.RuleContext<TMessageIds, TOptions>,
138
allowWithoutFullTypeInformation?: boolean
139
): TSESTree.ParserServices;
140
141
function applyDefault<TUser, TDefault>(
142
defaultOptions: Readonly<TDefault>,
143
userOptions: Readonly<TUser> | null
144
): TDefault;
145
146
class RuleTester {
147
constructor(baseOptions: TSESLint.RuleTesterConfig);
148
run<TMessageIds extends string, TOptions extends readonly unknown[]>(
149
name: string,
150
rule: TSESLint.RuleModule<TMessageIds, TOptions>,
151
tests: TSESLint.RunTests<TMessageIds, TOptions>
152
): void;
153
}
154
}
155
```
156
157
[ESLint Integration](./eslint-utils.md)
158
159
### TypeScript ESLint Types
160
161
Enhanced ESLint type definitions with full TypeScript integration for rules, contexts, and AST nodes.
162
163
```typescript { .api }
164
namespace TSESLint {
165
interface RuleModule<
166
TMessageIds extends string,
167
TOptions extends readonly unknown[],
168
TRuleListener extends RuleListener = RuleListener
169
> {
170
meta: RuleMetaData<TMessageIds>;
171
create(context: RuleContext<TMessageIds, TOptions>): TRuleListener;
172
defaultOptions?: TOptions;
173
}
174
175
interface RuleContext<TMessageIds extends string, TOptions extends readonly unknown[]> {
176
getAncestors(): TSESTree.Node[];
177
getDeclaredVariables(node: TSESTree.Node): TSESLintScope.Variable[];
178
getFilename(): string;
179
getScope(): TSESLintScope.Scope;
180
getSourceCode(): SourceCode;
181
markVariableAsUsed(name: string): boolean;
182
report(descriptor: ReportDescriptor<TMessageIds>): void;
183
settings: Record<string, unknown>;
184
options: TOptions;
185
}
186
}
187
```
188
189
[TypeScript ESLint Types](./ts-eslint.md)
190
191
### TypeScript ESTree
192
193
AST node definitions and parser services for TypeScript syntax trees.
194
195
```typescript { .api }
196
namespace TSESTree {
197
enum AST_NODE_TYPES {
198
ArrayExpression = 'ArrayExpression',
199
ArrayPattern = 'ArrayPattern',
200
ArrowFunctionExpression = 'ArrowFunctionExpression',
201
AssignmentExpression = 'AssignmentExpression',
202
AssignmentPattern = 'AssignmentPattern',
203
AwaitExpression = 'AwaitExpression',
204
// ... extensive enum of all AST node types
205
}
206
207
enum AST_TOKEN_TYPES {
208
Boolean = 'Boolean',
209
Identifier = 'Identifier',
210
JSXIdentifier = 'JSXIdentifier',
211
JSXText = 'JSXText',
212
Keyword = 'Keyword',
213
Null = 'Null',
214
Numeric = 'Numeric',
215
Punctuator = 'Punctuator',
216
RegularExpression = 'RegularExpression',
217
String = 'String',
218
Template = 'Template',
219
Block = 'Block',
220
Line = 'Line'
221
}
222
223
interface ParserServices {
224
program: ts.Program | null;
225
esTreeNodeToTSNodeMap: WeakMap<TSESTree.Node, ts.Node | ts.Token>;
226
tsNodeToESTreeNodeMap: WeakMap<ts.Node | ts.Token, TSESTree.Node>;
227
hasFullTypeInformation: boolean;
228
getSymbolAtLocation(node: TSESTree.Node): ts.Symbol | undefined;
229
getTypeAtLocation(node: TSESTree.Node): ts.Type;
230
}
231
}
232
```
233
234
[TypeScript ESTree](./ts-estree.md)
235
236
### Scope Analysis
237
238
Utilities for analyzing variable scopes, references, and bindings in TypeScript code.
239
240
```typescript { .api }
241
namespace TSESLintScope {
242
function analyze(
243
ast: TSESTree.Node,
244
options?: AnalysisOptions
245
): ScopeManager;
246
247
interface ScopeManager {
248
scopes: Scope[];
249
globalScope: GlobalScope | null;
250
acquire(node: TSESTree.Node, inner?: boolean): Scope | null;
251
getDeclaredVariables(node: TSESTree.Node): Variable[];
252
}
253
254
interface Scope {
255
type: ScopeType;
256
isStrict: boolean;
257
upper: Scope | null;
258
childScopes: Scope[];
259
variableScope: Scope;
260
block: TSESTree.Node;
261
variables: Variable[];
262
references: Reference[];
263
set: Map<string, Variable>;
264
through: Reference[];
265
}
266
267
const version: string;
268
}
269
```
270
271
[Scope Analysis](./scope-analysis.md)
272
273
### JSON Schema Types
274
275
Complete JSON Schema type definitions for rule configuration schemas.
276
277
```typescript { .api }
278
namespace JSONSchema {
279
interface JSONSchema7 {
280
$id?: string;
281
$ref?: string;
282
$schema?: string;
283
$comment?: string;
284
$defs?: Record<string, JSONSchema7Definition>;
285
286
title?: string;
287
description?: string;
288
default?: JSONSchema7Type;
289
readOnly?: boolean;
290
examples?: JSONSchema7Type[];
291
292
multipleOf?: number;
293
maximum?: number;
294
exclusiveMaximum?: number;
295
minimum?: number;
296
exclusiveMinimum?: number;
297
298
maxLength?: number;
299
minLength?: number;
300
pattern?: string;
301
302
additionalItems?: JSONSchema7Definition;
303
items?: JSONSchema7Definition | JSONSchema7Definition[];
304
maxItems?: number;
305
minItems?: number;
306
uniqueItems?: boolean;
307
contains?: JSONSchema7Definition;
308
309
maxProperties?: number;
310
minProperties?: number;
311
required?: string[];
312
additionalProperties?: JSONSchema7Definition;
313
definitions?: Record<string, JSONSchema7Definition>;
314
properties?: Record<string, JSONSchema7Definition>;
315
patternProperties?: Record<string, JSONSchema7Definition>;
316
dependencies?: Record<string, JSONSchema7Definition | string[]>;
317
propertyNames?: JSONSchema7Definition;
318
319
const?: JSONSchema7Type;
320
enum?: JSONSchema7Type[];
321
type?: JSONSchema7TypeName | JSONSchema7TypeName[];
322
323
format?: string;
324
contentMediaType?: string;
325
contentEncoding?: string;
326
327
if?: JSONSchema7Definition;
328
then?: JSONSchema7Definition;
329
else?: JSONSchema7Definition;
330
331
allOf?: JSONSchema7Definition[];
332
anyOf?: JSONSchema7Definition[];
333
oneOf?: JSONSchema7Definition[];
334
not?: JSONSchema7Definition;
335
}
336
337
type JSONSchema7Type = string | number | boolean | JSONSchema7Object | JSONSchema7Array | null;
338
type JSONSchema7TypeName = 'string' | 'number' | 'integer' | 'boolean' | 'object' | 'array' | 'null';
339
}
340
```
341
342
[JSON Schema Types](./json-schema.md)
343
344
## Types Used Across Capabilities
345
346
```typescript { .api }
347
// Core AST node union type
348
type Node = TSESTree.Node;
349
350
// Function-like nodes union
351
type FunctionLike = TSESTree.FunctionDeclaration | TSESTree.FunctionExpression | TSESTree.ArrowFunctionExpression;
352
353
// Token representation
354
interface Token {
355
type: string;
356
value: string;
357
range: [number, number];
358
loc: SourceLocation;
359
}
360
361
// Source location information
362
interface SourceLocation {
363
start: Position;
364
end: Position;
365
}
366
367
interface Position {
368
line: number;
369
column: number;
370
}
371
372
// Rule creation options
373
interface RuleMetaData<TMessageIds extends string> {
374
type: 'problem' | 'suggestion' | 'layout';
375
messages: Record<TMessageIds, string>;
376
fixable?: 'code' | 'whitespace';
377
schema: JSONSchema7 | JSONSchema7[];
378
deprecated?: boolean;
379
replacedBy?: string[];
380
docs?: {
381
description: string;
382
category?: string;
383
recommended?: boolean | 'error' | 'warn';
384
requiresTypeChecking?: boolean;
385
extendsBaseRule?: boolean | string;
386
};
387
}
388
389
// Test case definitions
390
interface ValidTestCase<TOptions extends readonly unknown[]> {
391
code: string;
392
options?: TOptions;
393
filename?: string;
394
parserOptions?: TSESLint.ParserOptions;
395
settings?: Record<string, unknown>;
396
parser?: string;
397
globals?: Record<string, boolean>;
398
env?: Linter.Environment;
399
}
400
401
interface InvalidTestCase<TMessageIds extends string, TOptions extends readonly unknown[]>
402
extends ValidTestCase<TOptions> {
403
errors: TestCaseError<TMessageIds>[];
404
output?: string | null;
405
}
406
```