【问题标题】:Typescript compiler, how to navigate to the definition of a symbol?Typescript编译器,如何导航到符号的定义?
【发布时间】:2019-11-17 00:40:52
【问题描述】:

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

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

提取信息:

// Analyzing file A
const defaultExportSymbolFileA = fileSymbol?.exports.get('default');
const type = typeChecker.getTypeOfSymbolAtLocation(defaultExportSymbolFileA, defaultExportSymbolFileA.valueDeclaration); // won't work

// Analyzing file B
const defaultExportSymbolFileB = fileSymbol?.exports.get('default');
const type = typeChecker.getTypeOfSymbolAtLocation(defaultExportSymbolFileB, defaultExportSymbolFileB.valueDeclaration); // works

谢谢!

【问题讨论】:

    标签: typescript-compiler-api


    【解决方案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() {}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-18
      • 2011-12-18
      • 1970-01-01
      • 1970-01-01
      • 2013-03-09
      相关资源
      最近更新 更多