TypeScript编译器:如何从CallExpression获取原始函数的FunctionDeclaration?

时间:2019-05-08 20:10:06

标签: typescript abstract-syntax-tree

我刚刚开始研究TypeScript内部结构,并且对如何在任意{{1 }}。

考虑示例:

Signature

给出对FunctionDeclaration CallExpression的引用,我可以很容易地用CallExpression来推断其物化类型及其返回值的类型。但是,我实际上想做的是获取原始函数的类型,即class A<T> { ... } function f<T>(): A<T> { return new A<T>(); } function test(): void { const foo = f; foo<number>(); } ,但不确定如何实现。

谢谢您的帮助!

1 个答案:

答案 0 :(得分:2)

您需要获取该类型的符号,然后才能获得该符号的声明:

import * as ts from 'typescript'

let p = ts.createProgram({
    rootNames: ["test.ts"],
    options: {

    }
})

const t = p.getTypeChecker();

var source = p.getSourceFile("test.ts");

const decl = source.statements[2] as ts.FunctionDeclaration; // function test(): void {....}
const fnCallStatement = decl.body.statements[1] as ts.ExpressionStatement; // foo<number>();
const fnCall = fnCallStatement.expression as ts.CallExpression; // foo<number>()
const fnTarget = fnCall.expression; // foo 
let type = t.getTypeAtLocation(fnTarget) // <T>() => A<T>
let symbol = type.getSymbol() // symbol: f
let fnDecl = symbol.getDeclarations()[0]
console.log(fnDecl.getFullText());
// output: 
// function f<T>(): A<T> {
//     return new A<T>();
// }