TypeScript AST Evaluator

2.0.0 · active · verified Sun Apr 19

ts-evaluator is an advanced interpreter for TypeScript that enables the evaluation of arbitrary AST (Abstract Syntax Tree) Nodes, specifically Expressions, ExpressionStatements, or Declarations, within a given TypeScript AST. Unlike tools such as `ts-node` that execute full TypeScript programs, this library focuses on partial evaluation based on a node's lexical environment. The current stable version is 2.0.0. Release cadence appears to be driven by significant TypeScript and JSDOM version updates, typically with several minor and patch releases in between. Its key differentiators include the ability to evaluate specific nodes, support for browser, Node.js, and pure ECMAScript environments, and configurable policy options for sandboxing and restricting operations like I/O or network access. This makes it a valuable tool for linters, language services, partial evaluators, and frameworks requiring deep AST introspection and computation.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to parse a TypeScript code string into an AST, locate a specific node (a binary expression in this case), and then use `ts-evaluator` to evaluate that node within a configured context, including a TypeChecker and policy restrictions.

import { evaluate, createEvaluationContext } from 'ts-evaluator';
import ts, { createSourceFile, ScriptTarget, SyntaxKind } from 'typescript';

const code = `
  const a = 10;
  const b = 'hello';
  function greet(name: string) { return 'Hello, ' + name + '!'; }
  const result = greet(b);
  const obj = { x: a, y: result };
  obj.x + 5;
`;

// Create a SourceFile from the code
const sourceFile = createSourceFile('example.ts', code, ScriptTarget.ES2016, true);

// Find the node to evaluate, e.g., 'obj.x + 5'
const nodeToEvaluate = sourceFile.forEachChild(node => {
  if (ts.isBinaryExpression(node) && ts.isPropertyAccessExpression(node.left) && node.left.name.text === 'x') {
    return node;
  }
  return undefined;
});

if (!nodeToEvaluate) {
  console.error('Could not find the node to evaluate.');
} else {
  // Create an evaluation context, optionally passing a TypeScript TypeChecker and policy options
  const context = createEvaluationContext({
    typeChecker: ts.createProgram([sourceFile.fileName], { target: ScriptTarget.ES2016 }).getTypeChecker(),
    // Example policy: disallow I/O operations
    policy: {
      disableIO: true,
      disableNetwork: true
    },
    // Initial lexical environment variables (if any)
    lexicalEnvironment: new Map()
  });

  // Evaluate the node
  const evaluationResult = evaluate(nodeToEvaluate, context);

  if (evaluationResult.success) {
    console.log(`Evaluation successful! Value: ${evaluationResult.value}`);
    // Expected output: Evaluation successful! Value: 15
  } else {
    console.error(`Evaluation failed: ${evaluationResult.reason}`);
  }
}

view raw JSON →