简体   繁体   English

如何使用 TypeScript Compiler API 查找环境模块声明的定义位置?

[英]How can I use the TypeScript Compiler API to find where an ambient module declaration is defined?

If something is defined in an ambient module declaration in another file:如果在另一个文件的环境模块声明中定义了某些内容:

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

and use the module:并使用模块:

import func from "@foo";

How can I use the TS Compiler API to find out where func is defined?如何使用 TS Compiler API 找出func的定义位置?

Normally, for figuring out where imports come from, I use ts.resolveModuleName , but it always returns undefined in this case.通常,为了确定导入的来源,我使用ts.resolveModuleName ,但在这种情况下它总是返回undefined

This is possible by following the symbols to the declaration.这可以通过遵循声明的符号来实现。

  1. Get the func identifier node.获取func标识符节点。
  2. Get its symbol, which will be local to the current file.获取它的符号,它将是当前文件的本地符号。
  3. Get the aliased symbol of that symbol, which will be the symbol of the declaration.获取该符号的别名符号,这将是声明的符号。
  4. Get that aliased symbol's declaration, which will be the function declaration.获取别名符号的声明,这将是函数声明。

Here's a contained example:这是一个包含的示例:

// 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());

Also, for getting the source file referenced in a module specifier, I still recommend getting the module specifier's symbol instead of using ts.resolveModuleName as outlined in this answer .此外,为了获取模块说明符中引用的源文件,我仍然建议获取模块说明符的符号,而不是使用本答案中概述的ts.resolveModuleName

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM