Typescript编译器,如何导航到符号定义?

时间:2019-11-16 01:06:10

标签: typescript-compiler-api

总体目标是从导出的模块中提取类型信息。但是,似乎需要导航到实际的定义,例如:

img-src 'self' http://0.0.0.0:5000
// fileA
function Foo() {...}
export default Foo

提取信息:

// fileB
export default function Foo() {...}

谢谢!

1 个答案:

答案 0 :(得分:1)

根据我的经验,如果在这种情况下该符号是别名,则需要获取别名符号。

function getDefaultExportDeclaration(fileSymbol: ts.Symbol) {
    if (fileSymbol.exports == null)
        return undefined;
    const defaultSymbol = fileSymbol.exports.get(ts.escapeLeadingUnderscores("default"));
    return defaultSymbol == null
        ? undefined
        : getAliasedSymbolIfNecessary(defaultSymbol).valueDeclaration;
}

function getAliasedSymbolIfNecessary(symbol: ts.Symbol) {
    if ((symbol.flags & ts.SymbolFlags.Alias) !== 0)
        return typeChecker.getAliasedSymbol(symbol);
    return symbol;
}

例如,使用以下使用此功能的代码:

// setup (this is my library that provides an easier setup with the compiler api)
import { Project, ts } from "@ts-morph/bootstrap";

const project = new Project();
const fileA = project.createSourceFile("fileA.ts", `function Foo() {} export default Foo;`);
const fileB = project.createSourceFile("fileB.ts", `export default function Foo() {}`);
const fileC = project.createSourceFile("fileC.ts", `import Foo from "./FileB";
export default Foo;`);

const program = project.createProgram();
const typeChecker = program.getTypeChecker();

// get result and output
console.log(getDefaultExportDeclaration(typeChecker.getSymbolAtLocation(fileA)!)!.getText());
console.log(getDefaultExportDeclaration(typeChecker.getSymbolAtLocation(fileB)!)!.getText());
console.log(getDefaultExportDeclaration(typeChecker.getSymbolAtLocation(fileC)!)!.getText());

输出将是:

function Foo() {}
export default function Foo() {}
export default function Foo() {}