Convert Figma logo to code with AI

phenomnomnominal logotsquery

TypeScript AST query library

1,008
30
1,008
12

Top Related Projects

103,639

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

25,435

Find and fix problems in your JavaScript code.

43,459

🐠 Babel is a compiler for writing next generation JavaScript.

49,809

Prettier is an opinionated code formatter.

:sparkles: Monorepo for all the tooling which enables ESLint to support TypeScript

8,992

JSHint is a tool that helps to detect errors and potential problems in your JavaScript code

Quick Overview

TSQuery is a TypeScript library that allows you to query TypeScript ASTs (Abstract Syntax Trees) using a CSS selector-like syntax. It provides a powerful and intuitive way to search and manipulate TypeScript code programmatically, making it useful for static analysis, code transformation, and other AST-based operations.

Pros

  • Intuitive CSS-like syntax for querying TypeScript ASTs
  • Supports a wide range of selectors and combinators
  • Integrates well with TypeScript's compiler API
  • Actively maintained and regularly updated

Cons

  • Learning curve for users unfamiliar with AST manipulation
  • Limited documentation and examples for advanced use cases
  • Performance may degrade with very large codebases
  • Requires understanding of TypeScript's AST structure

Code Examples

  1. Basic selector usage:
import { tsquery } from '@phenomnomnominal/tsquery';

const code = `
function greet(name: string) {
  console.log(\`Hello, \${name}!\`);
}
`;

const ast = tsquery.ast(code);
const functions = tsquery(ast, 'FunctionDeclaration');
console.log(functions.length); // Output: 1
  1. Finding specific identifiers:
import { tsquery } from '@phenomnomnominal/tsquery';

const code = `
const x = 1;
let y = 2;
var z = 3;
`;

const ast = tsquery.ast(code);
const constVariables = tsquery(ast, 'VariableDeclaration[kind="const"]');
console.log(constVariables.length); // Output: 1
  1. Combining selectors:
import { tsquery } from '@phenomnomnominal/tsquery';

const code = `
class MyClass {
  private myMethod() {
    return 42;
  }
}
`;

const ast = tsquery.ast(code);
const privateMethods = tsquery(ast, 'ClassDeclaration MethodDeclaration[modifiers.0.kind="PrivateKeyword"]');
console.log(privateMethods.length); // Output: 1

Getting Started

To use TSQuery in your project, follow these steps:

  1. Install the package:

    npm install @phenomnomnominal/tsquery
    
  2. Import and use in your TypeScript code:

    import { tsquery } from '@phenomnomnominal/tsquery';
    
    const code = `/* Your TypeScript code here */`;
    const ast = tsquery.ast(code);
    const results = tsquery(ast, 'YourSelector');
    
  3. Run your TypeScript code with ts-node or compile and run with tsc and node.

Competitor Comparisons

103,639

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

Pros of TypeScript

  • Comprehensive language implementation with full compiler and tooling support
  • Extensive documentation and large community backing
  • Regular updates and active development by Microsoft

Cons of TypeScript

  • Large codebase, which can be overwhelming for contributors
  • Slower to implement new features due to rigorous testing and compatibility requirements
  • More complex setup for local development and testing

Code Comparison

TypeScript (compiler core):

function createProgram(
  rootNames: readonly string[],
  options: CompilerOptions,
  host?: CompilerHost,
  oldProgram?: Program,
  configFileParsingDiagnostics?: readonly Diagnostic[]
): Program {
  // ... implementation
}

TSQuery:

export function tsquery(
  ast: ts.Node,
  query: string,
  opts: TSQueryOptions = {}
): TSQueryNode[] {
  // ... implementation
}

Key Differences

  • TypeScript is a full language implementation, while TSQuery is a utility for querying TypeScript ASTs
  • TypeScript's codebase is much larger and more complex
  • TSQuery focuses on a specific use case, making it more lightweight and easier to contribute to
  • TypeScript provides a complete development environment, whereas TSQuery is a tool to be used within TypeScript projects
25,435

Find and fix problems in your JavaScript code.

Pros of ESLint

  • Broader language support: Covers JavaScript, TypeScript, and various frameworks
  • Extensive rule set: Offers a wide range of customizable linting rules
  • Large ecosystem: Numerous plugins and configurations available

Cons of ESLint

  • Steeper learning curve: More complex setup and configuration process
  • Performance: Can be slower on large projects due to its comprehensive nature

Code Comparison

ESLint configuration example:

{
  "extends": "eslint:recommended",
  "rules": {
    "semi": ["error", "always"],
    "quotes": ["error", "double"]
  }
}

TSQuery usage example:

import { tsquery } from '@phenomnomnominal/tsquery';

const ast = tsquery.ast(`const x = 1;`);
const result = tsquery(ast, 'VariableDeclaration');

Key Differences

  • ESLint is a full-featured linter, while TSQuery is a query tool for TypeScript ASTs
  • ESLint focuses on enforcing coding standards, while TSQuery is designed for AST analysis and manipulation
  • ESLint has a more extensive configuration system, whereas TSQuery offers a simpler, more focused API

Use Cases

  • ESLint: Ideal for enforcing coding standards and catching potential errors in JavaScript and TypeScript projects
  • TSQuery: Better suited for specific TypeScript AST querying tasks, such as code analysis tools or custom transformations
43,459

🐠 Babel is a compiler for writing next generation JavaScript.

Pros of babel

  • Broader scope: Babel is a comprehensive JavaScript compiler with extensive transformation capabilities
  • Larger community and ecosystem: More plugins, integrations, and third-party support
  • Supports multiple languages and syntaxes beyond TypeScript

Cons of babel

  • Heavier and more complex: Requires more configuration and setup
  • Not TypeScript-specific: May lack some TypeScript-focused features and optimizations
  • Steeper learning curve for TypeScript-only projects

Code comparison

tsquery:

import { tsquery } from '@phenomnomnominal/tsquery';

const ast = tsquery.ast(`const x: number = 5;`);
const result = tsquery(ast, 'VariableDeclaration');

babel:

const babel = require('@babel/core');

const code = `const x: number = 5;`;
const result = babel.transform(code, {
  presets: ['@babel/preset-typescript']
});

Summary

tsquery is a lightweight, TypeScript-specific AST querying tool, while babel is a more comprehensive JavaScript compiler with broader language support. tsquery offers simplicity and focus for TypeScript projects, whereas babel provides greater flexibility and transformation capabilities across multiple languages and syntaxes.

49,809

Prettier is an opinionated code formatter.

Pros of Prettier

  • Widely adopted and supported by the community
  • Opinionated formatting with minimal configuration needed
  • Supports multiple languages beyond TypeScript

Cons of Prettier

  • Less granular control over specific formatting rules
  • May not handle complex TypeScript-specific syntax as effectively

Code Comparison

TSQuery:

import { tsquery } from 'tsquery';

const ast = tsquery.ast(`
  const x = 1;
  const y = 2;
`);

const result = tsquery(ast, 'VariableDeclaration');

Prettier:

const prettier = require("prettier");

const code = `
const x = 1;
const y = 2;
`;

const formattedCode = prettier.format(code, { parser: "typescript" });

Key Differences

  • TSQuery focuses on querying and manipulating TypeScript ASTs
  • Prettier is primarily for code formatting across multiple languages
  • TSQuery provides more fine-grained control for TypeScript-specific operations
  • Prettier aims for consistent, opinionated formatting with minimal configuration

Use Cases

  • Use TSQuery for advanced TypeScript static analysis and transformations
  • Choose Prettier for standardized code formatting across projects and teams

:sparkles: Monorepo for all the tooling which enables ESLint to support TypeScript

Pros of typescript-eslint

  • More comprehensive and actively maintained ESLint integration for TypeScript
  • Provides a wider range of rules and plugins specifically designed for TypeScript
  • Offers a unified parser for both JavaScript and TypeScript

Cons of typescript-eslint

  • More complex setup and configuration compared to tsquery
  • Larger package size and potential performance overhead
  • Steeper learning curve for customizing rules and plugins

Code Comparison

tsquery:

import { tsquery } from '@phenomnomnominal/tsquery';

const ast = tsquery.ast(`const x: number = 5;`);
const result = tsquery(ast, 'VariableDeclaration');

typescript-eslint:

module.exports = {
  parser: '@typescript-eslint/parser',
  plugins: ['@typescript-eslint'],
  extends: ['plugin:@typescript-eslint/recommended'],
  rules: {
    '@typescript-eslint/explicit-function-return-type': 'error',
  },
};

typescript-eslint provides a more comprehensive linting solution with extensive rule configurations, while tsquery focuses on querying TypeScript ASTs. typescript-eslint is better suited for large-scale projects requiring strict code quality enforcement, whereas tsquery is more lightweight and useful for specific AST analysis tasks.

8,992

JSHint is a tool that helps to detect errors and potential problems in your JavaScript code

Pros of JSHint

  • Broader language support: Analyzes JavaScript, while TSQuery focuses on TypeScript
  • More established project with a larger community and longer history
  • Offers a wider range of linting rules and configuration options

Cons of JSHint

  • Less focused on modern JavaScript/TypeScript features
  • Slower performance compared to TSQuery's targeted approach
  • More complex setup and configuration process

Code Comparison

TSQuery:

import { tsquery } from '@phenomnomnominal/tsquery';

const ast = tsquery.ast(`const x: number = 5;`);
const result = tsquery(ast, 'VariableDeclaration');

JSHint:

const JSHINT = require('jshint').JSHINT;

const code = 'const x = 5;';
JSHINT(code);
const errors = JSHINT.errors;

Key Differences

  • TSQuery is specifically designed for querying TypeScript ASTs, while JSHint is a more general-purpose JavaScript linter
  • TSQuery uses a CSS-like selector syntax for querying, whereas JSHint relies on predefined linting rules
  • JSHint provides a broader set of linting capabilities, while TSQuery offers more precise control over TypeScript-specific structures

Use Cases

  • Choose TSQuery for TypeScript-specific static analysis and AST querying
  • Opt for JSHint for general JavaScript linting and code quality checks in larger, established projects

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

TSQuery

npm version

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.

Demos:

ESQuery demo - note that the demo requires JavaScript code, not TypeScript TSQuery demo by Uri Shaked

Installation

npm install @phenomnomnominal/tsquery --save-dev

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 { ast, query } 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 = ast(typescript);
const nodes = query(ast, 'Identifier[name="Animal"]');
console.log(nodes.length); // 2

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 flow
  • FunctionDeclaration, ClassDeclaration, ArrowFunction - declarations
  • VariableStatement - var, const, let.
  • ImportDeclaration - any import statement
  • StringLiteral - any string
  • TrueKeyword, FalseKeyword, NullKeyword, AnyKeyword - various keywords
  • CallExpression - function call
  • NumericLiteral - any numeric constant
  • NoSubstitutionTemplateLiteral, TemplateExpression - template strings and expressions

API:

ast:

Parse a string of code into an Abstract Syntax Tree which can then be queried with TSQuery Selectors.

import { ast } from '@phenomnomnominal/tsquery';

const sourceFile = ast('const x = 1;');

includes:

Check for Nodes within a given string of code or AST Node matching a Selector.

import { includes } from '@phenomnomnominal/tsquery';

const hasIdentifier = includes('const x = 1;', 'Identifier');

map:

Transform AST Nodes within a given Node matching a Selector. Can be used to do Node-based replacement or removal of parts of the input AST.

import { factory } from 'typescript';
import { map } from '@phenomnomnominal/tsquery';

const tree = ast('const x = 1;')
const updatedTree = map(tree, 'Identifier', () => factory.createIdentifier('y'));

match:

Find AST Nodes within a given AST Node matching a Selector.

import { ast, match } from '@phenomnomnominal/tsquery';

const tree = ast('const x = 1;')
const [xNode] = match(tree, 'Identifier');

parse:

Parse a string into an ESQuery Selector.

import { parse } from '@phenomnomnominal/tsquery';

const selector = parse(':matches([attr] > :first-child, :last-child)');

print:

Print a given Node or SourceFile to a string, using the default TypeScript printer.

import { print } from '@phenomnomnominal/tsquery';
import { factory } from 'typescript';

  // create synthetic node:
const node = factory.createArrowFunction(
  // ...
);
const code = print(node);

project:

Get all the SourceFiles included in a the TypeScript project described by a given config file.

import { project } from '@phenomnomnominal/tsquery';

const files = project('./tsconfig.json');

files:

Get all the file paths included ina the TypeScript project described by a given config file.

import { files } from '@phenomnomnominal/tsquery';

const filePaths = files('./tsconfig.json');

match:

Find AST Nodes within a given string of code or AST Node matching a Selector.

import {query } from '@phenomnomnominal/tsquery';

const [xNode] = query('const x = 1;', 'Identifier');

replace:

Transform AST Nodes within a given Node matching a Selector. Can be used to do string-based replacement or removal of parts of the input AST. The updated code will be printed with the TypeScript Printer, so you may need to run your own formatter on any output code.

import { replace } from '@phenomnomnominal/tsquery';

const updatedCode = replace('const x = 1;', 'Identifier', () => 'y'));

NPM DownloadsLast 30 Days