What is @phenomnomnominal/tsquery?
The @phenomnomnominal/tsquery package is a powerful tool for querying TypeScript AST (Abstract Syntax Tree) using a CSS-like selector system. It allows developers to easily find nodes within TypeScript source code, making it useful for tasks such as code analysis, refactoring, and more.
What are @phenomnomnominal/tsquery's main functionalities?
Querying TypeScript AST
This feature allows you to query TypeScript AST nodes by using CSS-like selectors. In the provided code, `tsquery.ast` generates an AST from the source code, and `tsquery` function is used to find all identifiers named 'foo'.
import { tsquery } from '@phenomnomnominal/tsquery';
const ast = tsquery.ast(sourceCode);
const nodes = tsquery(ast, 'Identifier[name="foo"]');
Counting specific nodes
This feature is useful for analyzing the code to count specific types of statements or nodes. Here, the code counts how many 'IfStatement' nodes are in the provided source code.
import { tsquery } from '@phenomnomnominal/tsquery';
const ast = tsquery.ast(sourceCode);
const count = tsquery(ast, 'IfStatement').length;
Other packages similar to @phenomnomnominal/tsquery
typescript-eslint
typescript-eslint is a plugin that allows for linting TypeScript code with ESLint. It uses an AST to analyze the code, similar to tsquery, but is more focused on linting and enforcing coding standards rather than general querying.
ts-morph
ts-morph provides an easier API to work with the TypeScript compiler's AST. It offers functionalities similar to tsquery but with additional features like code manipulation and emitting, making it more versatile for tasks that involve modifying the codebase.
TSQuery
TSQuery is a port of the ESQuery API for TypeScript! TSQuery allows you to query a TypeScript AST for patterns of syntax using a CSS style selector system.
Check out the ESQuery demo - note that the demo requires JavaScript code, not TypeScript
You can also check out the TSQuery Playground - Lovingly crafted by Uri Shaked
Installation
npm install @phenomnomnominal/tsquery --save-dev
Upgrading from version 4.x.x to 5.x.x
Examples
Say we want to select all instances of an identifier with name "Animal", e.g. the identifier in the class
declaration, and the identifier in the extends
declaration.
We would do something like the following:
import { tsquery } from '@phenomnomnominal/tsquery';
const typescript = `
class Animal {
constructor(public name: string) { }
move(distanceInMeters: number = 0) {
console.log(\`\${this.name} moved \${distanceInMeters}m.\`);
}
}
class Snake extends Animal {
constructor(name: string) { super(name); }
move(distanceInMeters = 5) {
console.log("Slithering...");
super.move(distanceInMeters);
}
}
`;
const ast = tsquery.ast(typescript);
const nodes = tsquery(ast, 'Identifier[name="Animal"]');
console.log(nodes.length);
Try running this code in StackBlitz!
Selectors
The following selectors are supported:
Common AST node types
Identifier
- any identifier (name of a function, class, variable, etc)IfStatement
, ForStatement
, WhileStatement
, DoStatement
- control flowFunctionDeclaration
, ClassDeclaration
, ArrowFunction
- declarationsVariableStatement
- var, const, let.ImportDeclaration
- any import
statementStringLiteral
- any stringTrueKeyword
, FalseKeyword
, NullKeyword
, AnyKeyword
- various keywordsCallExpression
- function callNumericLiteral
- any numeric constantNoSubstitutionTemplateLiteral
, TemplateExpression
- template strings and expressions