【问题标题】:How can I use the TypeScript Compiler API to find where an ambient module declaration is defined?如何使用 TypeScript Compiler API 查找环境模块声明的定义位置?
【发布时间】:2020-04-01 23:01:14
【问题描述】:

如果在另一个文件的环境模块声明中定义了某些内容:

declare module "@foo" {
    export default function func(): number;
}

并使用模块:

import func from "@foo";

如何使用 TS Compiler API 找出 func 的定义位置?

通常,为了确定导入的来源,我使用ts.resolveModuleName,但在这种情况下它总是返回undefined

【问题讨论】:

    标签: typescript typescript-compiler-api


    【解决方案1】:

    这可以通过遵循声明的符号来实现。

    1. 获取func 标识符节点。
    2. 获取它的符号,它将是当前文件的本地。
    3. 获取该符号的别名符号,这将是声明的符号。
    4. 获取该别名符号的声明,即函数声明。

    这是一个包含的示例:

    // setup
    import { createProjectSync, ts } from "@ts-morph/bootstrap";
    
    const project = createProjectSync();
    project.createSourceFile("foo.d.ts", `declare module "@foo" { export default function func(): number; }`);
    const sourceFile = project.createSourceFile("file.ts", `import func from "@foo";`);
    const typeChecker = project.createProgram().getTypeChecker();
    
    // get the "func" identifier in the import declaration
    const importDec = sourceFile.statements[0] as ts.ImportDeclaration;
    const funcIdent = importDec.importClause!.name!;
    
    // follow the symbols to the function declaration
    const funcImportSymbol = typeChecker.getSymbolAtLocation(funcIdent)!;
    const funcDecSymbol = typeChecker.getAliasedSymbol(funcImportSymbol);
    const funcDec = funcDecSymbol.getDeclarations()![0];
    
    console.log(funcDec.getText());
    

    此外,为了获取模块说明符中引用的源文件,我仍然建议获取模块说明符的符号,而不是使用ts.resolveModuleName,如this answer 中所述。

    【讨论】:

    • 感谢您提供详细而仔细的回答!这将在 90% 的时间内有效。但是,由于与in the question you linked to 相同的原因,我们不能跳过中间符号:我们希望遵循模块图并收集所有引用的文件。
    • 我认为在这种情况下获取模块说明符的符号应该可以吗?我认为这种情况下不会有中间符号。
    • 好主意!我试试看。
    • 模块说明符是字符串文字,没有符号。 importClause 名称有符号,但 getAliasedSymbol(importClauseSymbol) 返回unknown
    • @MaxHeiber 使用typeChecker.getSymbolAtLocation(importDec.moduleSpecifier)
    猜你喜欢
    • 2012-10-12
    • 2014-10-16
    • 2019-10-14
    • 2019-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-29
    • 2020-05-07
    相关资源
    最近更新 更多