You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用TypeScript Compiler API在AST树中查找特定SyntaxKind节点?

使用TypeScript Compiler API遍历AST查找特定类型节点

你之前的代码只获取了当前节点的直接子节点,没有递归遍历子节点的子节点,所以没法覆盖整棵AST树。要实现通用的findNodes函数,核心是要做深度优先的递归遍历,结合TypeScript提供的类型守卫函数(比如isReturnStatement、isClassDeclaration)筛选节点。

完整实现代码

import * as ts from "typescript";

/**
 * 递归遍历AST树,查找所有符合类型守卫条件的节点
 * @param node 起始节点
 * @param typeGuard 类型守卫函数,用于判断节点是否符合目标类型
 * @returns 所有符合条件的节点数组
 */
function findNodes<T extends ts.Node>(node: ts.Node, typeGuard: (node: ts.Node) => node is T): T[] {
  const result: T[] = [];

  // 先检查当前节点是否符合条件
  if (typeGuard(node)) {
    result.push(node);
  }

  // 递归遍历所有子节点
  ts.forEachChild(node, (child) => {
    result.push(...findNodes(child, typeGuard));
  });

  return result;
}

// 示例用法
// 假设你已经有了一个AST根节点(比如通过ts.createSourceFile解析得到的sourceFile)
const sourceFile = ts.createSourceFile(
  "test.ts",
  `
class TestClass {
  method() {
    return 123;
  }
}

function foo() {
  return "hello";
}
  `,
  ts.ScriptTarget.Latest,
  true
);

// 查找所有ReturnStatement节点
const returnStatements = findNodes(sourceFile, ts.isReturnStatement);
console.log("找到的ReturnStatement数量:", returnStatements.length); // 输出2

// 查找所有ClassDeclaration节点
const classDeclarations = findNodes(sourceFile, ts.isClassDeclaration);
console.log("找到的ClassDeclaration数量:", classDeclarations.length); // 输出1

关键说明

  • ts.forEachChild会遍历当前节点的所有直接子节点,但不会自动递归,所以我们需要在遍历子节点时再次调用findNodes,实现深度遍历。
  • TypeScript提供的isXXX函数(比如ts.isReturnStatement)是类型守卫,不仅能判断节点类型,还能让TypeScript推断出返回数组的具体类型,保证类型安全。
  • 这个函数是通用的,只要传入对应的类型守卫函数,就能查找任意类型的AST节点。

内容的提问来源于stack exchange,提问作者Ced

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 15:14:56