【问题标题】:Correct way of getting type for a variable declaration in a typescript AST?在打字稿AST中获取变量声明类型的正确方法?
【发布时间】:2016-01-18 04:45:12
【问题描述】:

查看declarationEmitter,对于变量声明,它具有函数#emitVariableDeclaration,最终调用#writeTypeOfDeclaration。这段代码做了所说的——它接受一个变量声明并打印变量及其类型——这正是我想要做的。

问题在于,当我复制此代码时,VariableDeclaration 节点没有符号属性……因此,类型始终为“任何”。 是否缺少初始化“符号”的步骤?

//sample input filecontents
export const foo = '123'

//mycode.js
const ast = ts.createSourceFile(filename, filecontents, ts.ScriptTarget.ES6, true))
const program = ts.createProgram([filename], {});
const typeChecker = program.getDiagnosticsProducingTypeChecker()
const emitResolver = typeChecker.getEmitResolver(filename)
// variableDeclarationNode --- can be obtained using ts.forEachChild and finding node with kind === ts.SyntaxKind.VariableDeclaration
// writer --- an object implementing the SymbolWriter interface that just concatenates to a result string
emitResolver.writeTypeOfDeclaration(variableDeclarationNode, undefined, undefined, writer)

//declarationEmitter.ts
function writeTypeOfDeclaration(
      declaration: AccessorDeclaration | VariableLikeDeclaration, 
      type: TypeNode, 
      getSymbolAccessibilityDiagnostic: GetSymbolAccessibilityDiagnostic) {
   //...
   resolver.writeTypeOfDeclaration(declaration, enclosingDeclaration, TypeFormatFlags.UseTypeOfFunction, writer);
}

//`checker.ts`
function writeTypeOfDeclaration(
    declaration: AccessorDeclaration | VariableLikeDeclaration,       
    enclosingDeclaration: Node, 
    flags: TypeFormatFlags, 
    writer: SymbolWriter) {

    // Get type of the symbol if this is the valid symbol otherwise get type at location
    const symbol = getSymbolOfNode(declaration);
    const type = symbol && !(symbol.flags & (SymbolFlags.TypeLiteral | SymbolFlags.Signature))
        ? getTypeOfSymbol(symbol)
        : unknownType;

    // ....
}

function getMergedSymbol(symbol: Symbol): Symbol {
    let merged: Symbol;
    return symbol && symbol.mergeId && (merged = mergedSymbols[symbol.mergeId]) ? merged : symbol;
}

function getSymbolOfNode(node: Node): Symbol {
    return getMergedSymbol(node.symbol);
}

【问题讨论】:

    标签: typescript abstract-syntax-tree context-free-grammar typescript1.6 typescript1.7


    【解决方案1】:

    原来我使用了错误的 AST。在问题中,我使用的是没有类型的 AST。您可以获得带有程序注入类型的 AST。 (更)正确的解决方案是:

    const program = ts.createProgram(filename, {target: ts.ScriptTarget.ES6, module: ts.ModuleKind.ES6});
    const typechecker = program.getDiagnosticsProducingTypeChecker()
    const emitResolver = typeChecker.getEmitResolver(filename)))
    
    // THIS IS HOW TO GET AN AST WITH TYPE (Yes, it's called a "SourceFile")
    const ast = program.getSourceFile(filename)
    
    // variableDeclarationNode --- can be obtained using ts.forEachChild and finding node with kind === ts.SyntaxKind.VariableDeclaration
    // writer --- an object implementing the SymbolWriter interface that just concatenates to a result string
    emitResolver.writeTypeOfDeclaration(variableDeclarationNode, undefined, undefined, writer)
    

    【讨论】:

    • 是的。您需要使用该程序:)
    • getEmitResolver 是一个内部 API。是否有公共 API 可供使用?
    【解决方案2】:

    是否缺少初始化“符号”的步骤?

    这是binder的工作。

    一些文档:https://basarat.gitbooks.io/typescript/content/docs/compiler/binder.html

    【讨论】:

    • 具体的例子会有所帮助。真的不在乎编译器如何在内部工作......需要使用这个外部
    • 内部部分只是遵循控制台中编译器的外部用法。但我看到你找到了答案:)
    猜你喜欢
    • 2017-06-10
    • 1970-01-01
    • 2019-01-14
    • 1970-01-01
    • 2019-02-16
    • 1970-01-01
    • 2021-01-20
    • 2021-01-12
    • 2021-06-16
    相关资源
    最近更新 更多