在打字稿AST中获取变量声明的类型的正确方法? [英] Correct way of getting type for a variable declaration in a typescript AST?

查看:126
本文介绍了在打字稿AST中获取变量声明的类型的正确方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

看看 declarationEmitter ,对于变量声明,它具有函数 #emitVariableDeclaration ,该函数最终会调用 #writeTypeOfDeclaration .这段代码执行了所说的操作-它需要一个变量声明,并输出该变量及其类型-这正是我要执行的操作.

Took a look at the declarationEmitter and for variable declarations, it has the function #emitVariableDeclaration which eventually calls #writeTypeOfDeclaration. This code does what is says---it takes a variable declaration and prints the variable and its type---this is exactly what I want to do.

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

The problem is that when I replicate this code, the VariableDeclaration node has no symbol property...and thus, the type is always "any". Is there a missing step to initialize "symbols"?

//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.您可以通过程序注入的类型获得AST.正确的解决方案是:

It turns out I was using the wrong AST. In the question, I'm using the AST that doesn't have type. You can get the AST with type injected with the program. The (more) correct solution is:

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)

这篇关于在打字稿AST中获取变量声明的类型的正确方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆