UNPKG

13.7 kBMarkdownView Raw
1<h1 align="center">TypeScript ESTree</h1>
2
3<p align="center">A parser that converts TypeScript source code into an <a href="https://github.com/estree/estree">ESTree</a>-compatible form</p>
4
5<p align="center">
6 <img src="https://github.com/typescript-eslint/typescript-eslint/workflows/CI/badge.svg" alt="CI" />
7 <a href="https://www.npmjs.com/package/@typescript-eslint/typescript-estree"><img src="https://img.shields.io/npm/v/@typescript-eslint/typescript-estree.svg?style=flat-square" alt="NPM Version" /></a>
8 <a href="https://www.npmjs.com/package/@typescript-eslint/typescript-estree"><img src="https://img.shields.io/npm/dm/@typescript-eslint/typescript-estree.svg?style=flat-square" alt="NPM Downloads" /></a>
9</p>
10
11## Getting Started
12
13**[You can find our Getting Started docs here](../../docs/getting-started/linting/README.md)**
14
15## About
16
17This parser is somewhat generic and robust, and could be used to power any use-case which requires taking TypeScript source code and producing an ESTree-compatible AST.
18
19In fact, it is already used within these hyper-popular open-source projects to power their TypeScript support:
20
21- [ESLint](https://eslint.org), the pluggable linting utility for JavaScript and JSX
22- [Prettier](https://prettier.io), an opinionated code formatter
23
24## Installation
25
26```sh
27yarn add -D @typescript-eslint/typescript-estree
28```
29
30## API
31
32### Parsing
33
34#### `parse(code, options)`
35
36Parses the given string of code with the options provided and returns an ESTree-compatible AST.
37
38```ts
39interface ParseOptions {
40 /**
41 * create a top-level comments array containing all comments
42 */
43 comment?: boolean;
44
45 /**
46 * An array of modules to turn explicit debugging on for.
47 * - 'typescript-eslint' is the same as setting the env var `DEBUG=typescript-eslint:*`
48 * - 'eslint' is the same as setting the env var `DEBUG=eslint:*`
49 * - 'typescript' is the same as setting `extendedDiagnostics: true` in your tsconfig compilerOptions
50 *
51 * For convenience, also supports a boolean:
52 * - true === ['typescript-eslint']
53 * - false === []
54 */
55 debugLevel?: boolean | ('typescript-eslint' | 'eslint' | 'typescript')[];
56
57 /**
58 * Cause the parser to error if it encounters an unknown AST node type (useful for testing).
59 * This case only usually occurs when TypeScript releases new features.
60 */
61 errorOnUnknownASTType?: boolean;
62
63 /**
64 * Absolute (or relative to `cwd`) path to the file being parsed.
65 */
66 filePath?: string;
67
68 /**
69 * Enable parsing of JSX.
70 * For more details, see https://www.typescriptlang.org/docs/handbook/jsx.html
71 *
72 * NOTE: this setting does not effect known file types (.js, .jsx, .ts, .tsx, .json) because the
73 * TypeScript compiler has its own internal handling for known file extensions.
74 *
75 * For the exact behavior, see https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/parser#parseroptionsecmafeaturesjsx
76 */
77 jsx?: boolean;
78
79 /**
80 * Controls whether the `loc` information to each node.
81 * The `loc` property is an object which contains the exact line/column the node starts/ends on.
82 * This is similar to the `range` property, except it is line/column relative.
83 */
84 loc?: boolean;
85
86 /*
87 * Allows overriding of function used for logging.
88 * When value is `false`, no logging will occur.
89 * When value is not provided, `console.log()` will be used.
90 */
91 loggerFn?: Function | false;
92
93 /**
94 * Controls whether the `range` property is included on AST nodes.
95 * The `range` property is a [number, number] which indicates the start/end index of the node in the file contents.
96 * This is similar to the `loc` property, except this is the absolute index.
97 */
98 range?: boolean;
99
100 /**
101 * Set to true to create a top-level array containing all tokens from the file.
102 */
103 tokens?: boolean;
104}
105
106const PARSE_DEFAULT_OPTIONS: ParseOptions = {
107 comment: false,
108 errorOnUnknownASTType: false,
109 filePath: 'estree.ts', // or 'estree.tsx', if you pass jsx: true
110 jsx: false,
111 loc: false,
112 loggerFn: undefined,
113 range: false,
114 tokens: false,
115};
116
117declare function parse(
118 code: string,
119 options: ParseOptions = PARSE_DEFAULT_OPTIONS,
120): TSESTree.Program;
121```
122
123Example usage:
124
125```js
126import { parse } from '@typescript-eslint/typescript-estree';
127
128const code = `const hello: string = 'world';`;
129const ast = parse(code, {
130 loc: true,
131 range: true,
132});
133```
134
135#### `parseAndGenerateServices(code, options)`
136
137Parses the given string of code with the options provided and returns an ESTree-compatible AST. Accepts additional options which can be used to generate type information along with the AST.
138
139```ts
140interface ParseAndGenerateServicesOptions extends ParseOptions {
141 /**
142 * Causes the parser to error if the TypeScript compiler returns any unexpected syntax/semantic errors.
143 */
144 errorOnTypeScriptSyntacticAndSemanticIssues?: boolean;
145
146 /**
147 * ***EXPERIMENTAL FLAG*** - Use this at your own risk.
148 *
149 * Causes TS to use the source files for referenced projects instead of the compiled .d.ts files.
150 * This feature is not yet optimized, and is likely to cause OOMs for medium to large projects.
151 *
152 * This flag REQUIRES at least TS v3.9, otherwise it does nothing.
153 *
154 * See: https://github.com/typescript-eslint/typescript-eslint/issues/2094
155 */
156 EXPERIMENTAL_useSourceOfProjectReferenceRedirect?: boolean;
157
158 /**
159 * When `project` is provided, this controls the non-standard file extensions which will be parsed.
160 * It accepts an array of file extensions, each preceded by a `.`.
161 */
162 extraFileExtensions?: string[];
163
164 /**
165 * Absolute (or relative to `tsconfigRootDir`) path to the file being parsed.
166 * When `project` is provided, this is required, as it is used to fetch the file from the TypeScript compiler's cache.
167 */
168 filePath?: string;
169
170 /**
171 * Allows the user to control whether or not two-way AST node maps are preserved
172 * during the AST conversion process.
173 *
174 * By default: the AST node maps are NOT preserved, unless `project` has been specified,
175 * in which case the maps are made available on the returned `parserServices`.
176 *
177 * NOTE: If `preserveNodeMaps` is explicitly set by the user, it will be respected,
178 * regardless of whether or not `project` is in use.
179 */
180 preserveNodeMaps?: boolean;
181
182 /**
183 * Absolute (or relative to `tsconfigRootDir`) paths to the tsconfig(s).
184 * If this is provided, type information will be returned.
185 */
186 project?: string | string[];
187
188 /**
189 * If you provide a glob (or globs) to the project option, you can use this option to ignore certain folders from
190 * being matched by the globs.
191 * This accepts an array of globs to ignore.
192 *
193 * By default, this is set to ["/node_modules/"]
194 */
195 projectFolderIgnoreList?: string[];
196
197 /**
198 * The absolute path to the root directory for all provided `project`s.
199 */
200 tsconfigRootDir?: string;
201
202 /**
203 * An array of one or more instances of TypeScript Program objects to be used for type information.
204 * This overrides any program or programs that would have been computed from the `project` option.
205 * All linted files must be part of the provided program(s).
206 */
207 programs?: Program[];
208
209 /**
210 ***************************************************************************************
211 * IT IS RECOMMENDED THAT YOU DO NOT USE THIS OPTION, AS IT CAUSES PERFORMANCE ISSUES. *
212 ***************************************************************************************
213 *
214 * When passed with `project`, this allows the parser to create a catch-all, default program.
215 * This means that if the parser encounters a file not included in any of the provided `project`s,
216 * it will not error, but will instead parse the file and its dependencies in a new program.
217 */
218 createDefaultProgram?: boolean;
219
220 /**
221 * ESLint (and therefore typescript-eslint) is used in both "single run"/one-time contexts,
222 * such as an ESLint CLI invocation, and long-running sessions (such as continuous feedback
223 * on a file in an IDE).
224 *
225 * When typescript-eslint handles TypeScript Program management behind the scenes, this distinction
226 * is important because there is significant overhead to managing the so called Watch Programs
227 * needed for the long-running use-case.
228 *
229 * When allowAutomaticSingleRunInference is enabled, we will use common heuristics to infer
230 * whether or not ESLint is being used as part of a single run.
231 */
232 allowAutomaticSingleRunInference?: boolean;
233
234 /**
235 * Path to a file exporting a custom ModuleResolver.
236 */
237 moduleResolver?: string;
238}
239
240interface ParserServices {
241 program: ts.Program;
242 esTreeNodeToTSNodeMap: WeakMap<TSESTree.Node, ts.Node | ts.Token>;
243 tsNodeToESTreeNodeMap: WeakMap<ts.Node | ts.Token, TSESTree.Node>;
244 hasFullTypeInformation: boolean;
245}
246
247interface ParseAndGenerateServicesResult<T extends TSESTreeOptions> {
248 ast: TSESTree.Program;
249 services: ParserServices;
250}
251
252const PARSE_AND_GENERATE_SERVICES_DEFAULT_OPTIONS: ParseOptions = {
253 ...PARSE_DEFAULT_OPTIONS,
254 errorOnTypeScriptSyntacticAndSemanticIssues: false,
255 extraFileExtensions: [],
256 preserveNodeMaps: false, // or true, if you do not set this, but pass `project`
257 project: undefined,
258 projectFolderIgnoreList: ['/node_modules/'],
259 tsconfigRootDir: process.cwd(),
260};
261
262declare function parseAndGenerateServices(
263 code: string,
264 options: ParseOptions = PARSE_DEFAULT_OPTIONS,
265): ParseAndGenerateServicesResult;
266```
267
268Example usage:
269
270```js
271import { parseAndGenerateServices } from '@typescript-eslint/typescript-estree';
272
273const code = `const hello: string = 'world';`;
274const { ast, services } = parseAndGenerateServices(code, {
275 filePath: '/some/path/to/file/foo.ts',
276 loc: true,
277 project: './tsconfig.json',
278 range: true,
279});
280```
281
282#### `parseWithNodeMaps(code, options)`
283
284Parses the given string of code with the options provided and returns both the ESTree-compatible AST as well as the node maps.
285This allows you to work with both ASTs without the overhead of types that may come with `parseAndGenerateServices`.
286
287```ts
288interface ParseWithNodeMapsResult<T extends TSESTreeOptions> {
289 ast: TSESTree.Program;
290 esTreeNodeToTSNodeMap: ParserServices['esTreeNodeToTSNodeMap'];
291 tsNodeToESTreeNodeMap: ParserServices['tsNodeToESTreeNodeMap'];
292}
293
294declare function parseWithNodeMaps(
295 code: string,
296 options: ParseOptions = PARSE_DEFAULT_OPTIONS,
297): ParseWithNodeMapsResult;
298```
299
300Example usage:
301
302```js
303import { parseWithNodeMaps } from '@typescript-eslint/typescript-estree';
304
305const code = `const hello: string = 'world';`;
306const { ast, esTreeNodeToTSNodeMap, tsNodeToESTreeNodeMap } = parseWithNodeMaps(
307 code,
308 {
309 loc: true,
310 range: true,
311 },
312);
313```
314
315### `TSESTree`, `AST_NODE_TYPES` and `AST_TOKEN_TYPES`
316
317Types for the AST produced by the parse functions.
318
319- `TSESTree` is a namespace which contains object types representing all of the AST Nodes produced by the parser.
320- `AST_NODE_TYPES` is an enum which provides the values for every single AST node's `type` property.
321- `AST_TOKEN_TYPES` is an enum which provides the values for every single AST token's `type` property.
322
323### Utilities
324
325#### `createProgram(configFile, projectDirectory)`
326
327This serves as a utility method for users of the `ParseOptions.programs` feature to create a TypeScript program instance from a config file.
328
329```ts
330declare function createProgram(
331 configFile: string,
332 projectDirectory: string = process.cwd(),
333): import('typescript').Program;
334```
335
336Example usage:
337
338```js
339const tsESTree = require('@typescript-eslint/typescript-estree');
340
341const program = tsESTree.createProgram('tsconfig.json');
342const code = `const hello: string = 'world';`;
343const { ast, services } = parseAndGenerateServices(code, {
344 filePath: '/some/path/to/file/foo.ts',
345 loc: true,
346 program,
347 range: true,
348});
349```
350
351## Supported TypeScript Version
352
353See the [Supported TypeScript Version](../../README.md#supported-typescript-version) section in the project root.
354
355If you use a non-supported version of TypeScript, the parser will log a warning to the console.
356
357**Please ensure that you are using a supported version before submitting any issues/bug reports.**
358
359## Reporting Issues
360
361Please check the current list of open and known issues and ensure the issue has not been reported before. When creating a new issue provide as much information about your environment as possible. This includes:
362
363- TypeScript version
364- The `typescript-estree` version
365
366## AST Alignment Tests
367
368A couple of years after work on this parser began, the TypeScript Team at Microsoft began [officially supporting TypeScript parsing via Babel](https://blogs.msdn.microsoft.com/typescript/2018/08/27/typescript-and-babel-7/).
369
370I work closely with the TypeScript Team and we are gradually aligning the AST of this project with the one produced by Babel's parser. To that end, I have created a full test harness to compare the ASTs of the two projects which runs on every PR, please see [the code](https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/typescript-estree/tests/ast-alignment) for more details.
371
372## Debugging
373
374If you encounter a bug with the parser that you want to investigate, you can turn on the debug logging via setting the environment variable: `DEBUG=typescript-eslint:*`.
375I.e. in this repo you can run: `DEBUG=typescript-eslint:* yarn lint`.
376
377## License
378
379TypeScript ESTree inherits from the the original TypeScript ESLint Parser license, as the majority of the work began there. It is licensed under a permissive BSD 2-clause license.
380
381## Contributing
382
383[See the contributing guide here](../../CONTRIBUTING.md)