typescript - 在 typescript AST 中获取变量声明类型的正确方法?

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

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

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

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

最佳答案

事实证明我使用了错误的 AST。在问题中,我使用的是没有类型的 AST。您可以获得程序注入(inject)类型的 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)

关于typescript - 在 typescript AST 中获取变量声明类型的正确方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34847471/

相关文章:

typescript - typescript如何像js数组中的map函数一样转换union类型的各个类型

javascript - tsc out 创建空输出文件

python - 如何调试 `ast.literal_eval` 中的错误?

java - 如何查找从哪些 Method 方法调用以及在其中声明变量

ruby - 如何手动构建 AST?

programming-languages - 如何证明给定语法的正确性?

javascript - 在 typescript 中声明 for in 循环的键类型

javascript - 将嵌入的内容传递给嵌套列表的孙组件

regex - 非正则上下文无关语言和无限正则子语言

compiler-construction - 编译器如何在解析器过程中区分负数和负数