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

如何用ts-morph或TypeScript编译器API查找函数调用关系?

使用 ts-morph/TypeScript 编译器API 追踪函数调用关系

核心:从调用表达式定位对应函数声明

你已经能获取函数声明和函数体内的调用表达式,接下来关键是靠TypeScript的类型检查器(TypeChecker)解析调用表达式对应的符号(Symbol),进而找到关联的函数声明。

用 ts-morph 实现的具体操作

  • 先拿到类型检查器
    不管是从整个项目还是单个源文件,先获取TypeChecker实例——这是解析符号的核心:

    const typeChecker = project.getTypeChecker(); // project是你创建的ts-morph Project实例
    
  • 解析调用表达式的符号
    遍历每个函数里的CallExpression,调用getSymbol()拿到对应的符号,注意跳过无效的调用:

    functionDeclaration.getChildrenOfKind(SyntaxKind.CallExpression).forEach(callExpr => {
      const symbol = typeChecker.getSymbolAtLocation(callExpr.expression);
      if (!symbol) return; // 比如全局未定义的函数,这里会拿不到符号
    });
    
  • 从符号找到函数声明
    符号的getDeclarations()会返回该符号的所有声明节点,筛选出函数声明类型即可:

    const targetFuncs = symbol.getDeclarations()?.filter(
      decl => decl.getKind() === SyntaxKind.FunctionDeclaration
    ) as FunctionDeclaration[];
    

    这里要注意:如果调用的是第三方库或全局函数,可能拿不到本地的声明节点,得确保这些代码在TypeScript的类型检查范围内。

  • 处理方法调用这类特殊场景
    比如obj.foo()这种方法调用,不能直接解析整个表达式,得拆分处理:

    if (callExpr.expression.getKind() === SyntaxKind.PropertyAccessExpression) {
      const propAccess = callExpr.expression as PropertyAccessExpression;
      const methodSymbol = typeChecker.getSymbolAtLocation(propAccess.name);
      // 后续同样用getDeclarations()找方法的声明节点
    }
    

用 TypeScript 原生编译器API 实现的思路

逻辑和ts-morph完全一致,只是API更底层:

  • 通过program.getTypeChecker()获取类型检查器
  • 遍历源文件里的函数声明,找到函数体内的CallExpression节点
  • 对调用表达式的expression节点,调用typeChecker.getSymbolAtLocation()获取符号
  • 从符号的declarations数组里筛选出FunctionDeclaration或FunctionExpression类型的节点

几个要注意的点

  • 跨文件调用:得把所有相关文件都加入项目/程序,不然类型检查器没法解析跨文件的符号
  • 重载函数:getDeclarations()可能返回多个重载声明,需要结合调用时的参数进一步匹配
  • 匿名/箭头函数:这类函数没有命名符号,没法用这个方法直接追踪,得结合上下文分析

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 22:33:08