1

查看了declarationEmitter和变量声明,它具有函数#emitVariableDeclaration,最终调用#writeTypeOfDeclaration。这段代码没有做什么说---它需要一个变量声明并打印变量及其类型---这正是我想要做的。在打字稿AST中为变量声明获取类型的正确方法?

问题是,当我复制此代码时,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); 
} 

回答

0

原来我用错了AST。在问题中,我使用的是没有类型的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) 
+0

是的。您需要使用该程序:) – basarat

+0

'getEmitResolver'是一个内部API。有没有公​​共的API可以使用? – Josh