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

如何通过TypeScript Compiler API查找TS文件中的全局变量与标识符?

查找TypeScript文件中的全局标识符(变量与函数)

你当前的代码仅捕获了VariableDeclaration节点,无法覆盖全局作用域下的所有标识符类型。要实现需求,需要扩展AST节点的判断逻辑,同时严格限定只处理全局作用域内的节点,避免误判函数/类内部的局部标识符。

核心思路

TypeScript的AST中,全局作用域的顶层标识符对应这些节点类型:

  • VariableStatement:对应let/const/var声明的全局变量
  • FunctionDeclaration:全局函数声明
  • PropertyDeclaration:无关键字的全局变量(比如你示例中的thisIsAGlobalVariable: any;)
  • 可选:InterfaceDeclaration/TypeAliasDeclaration(如果需要捕获全局类型标识符)

修正后的实现代码

import * as vscode from 'vscode';
import * as ts from 'typescript';

function findGlobalIdentifiers(editor: vscode.TextEditor): string[] {
    const text = editor.document.getText();
    const globalIdentifiers: string[] = [];
    const sourceFile = ts.createSourceFile('temp.ts', text, ts.ScriptTarget.Latest, true);

    const visit = (node: ts.Node) => {
        // 仅处理全局作用域的顶层节点
        if (node.parent === sourceFile) {
            // 处理let/const/var声明的全局变量
            if (ts.isVariableStatement(node)) {
                node.declarationList.declarations.forEach(decl => {
                    if (ts.isIdentifier(decl.name)) {
                        globalIdentifiers.push(decl.name.text);
                    }
                });
            }
            // 处理全局函数
            else if (ts.isFunctionDeclaration(node) && node.name) {
                globalIdentifiers.push(node.name.text);
            }
            // 处理无关键字的全局变量(如`foo: any;`)
            else if (ts.isPropertyDeclaration(node)) {
                if (ts.isIdentifier(node.name)) {
                    globalIdentifiers.push(node.name.text);
                }
            }
            // 可选:开启以下代码捕获全局接口/类型别名
            // else if (ts.isInterfaceDeclaration(node)) {
            //     globalIdentifiers.push(node.name.text);
            // }
            // else if (ts.isTypeAliasDeclaration(node)) {
            //     globalIdentifiers.push(node.name.text);
            // }
        }
        ts.forEachChild(node, visit);
    };

    visit(sourceFile);
    // 去重处理,避免重复声明的标识符多次出现
    return [...new Set(globalIdentifiers)];
}

代码说明

  1. 作用域过滤:通过node.parent === sourceFile确保只处理全局作用域的顶层节点,排除函数、类内部的局部变量/函数。
  2. 多类型覆盖:覆盖了你提到的所有全局标识符形式,包括无关键字的变量声明和全局函数。
  3. 去重处理:使用Set对结果去重,避免同一标识符多次声明导致的重复条目。

测试验证

针对你给出的示例代码:

thisIsAGlobalVariable: any;
thisIsAnotherGlobalVariable;
thisIsYetAnotherGlobalVariable = "hello";
function globalFunc() {}
const globalConst = 123;

运行代码后会返回:["thisIsAGlobalVariable", "thisIsAnotherGlobalVariable", "thisIsYetAnotherGlobalVariable", "globalFunc", "globalConst"]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 23:55:18