TypeScript 编译器:如何从 CallExpression 获取原始函数的 FunctionDeclaration?
TypeScript Compiler: how to get FunctionDeclaration of the original function from CallExpression?
我刚刚开始研究 TypeScript 的内部结构,我很困惑如何在任意 CallExpression
.
考虑示例:
class A<T> {
...
}
function f<T>(): A<T> {
return new A<T>();
}
function test(): void {
const foo = f;
foo<number>();
}
给出对 foo<number>()
CallExpression 的引用,我可以很容易地推断出它的具体化类型以及它的 return 值与 typechecker.getTypeAtLocation(node)
的类型。但是,我实际上想做的是获取原始函数的类型,即 function f<T>(): A<T> { ... }
,我不确定如何实现。
如有任何帮助,我将不胜感激,谢谢!
您需要获取该类型的符号,然后您可以获得该符号的声明:
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>();
// }
我刚刚开始研究 TypeScript 的内部结构,我很困惑如何在任意 CallExpression
.
考虑示例:
class A<T> {
...
}
function f<T>(): A<T> {
return new A<T>();
}
function test(): void {
const foo = f;
foo<number>();
}
给出对 foo<number>()
CallExpression 的引用,我可以很容易地推断出它的具体化类型以及它的 return 值与 typechecker.getTypeAtLocation(node)
的类型。但是,我实际上想做的是获取原始函数的类型,即 function f<T>(): A<T> { ... }
,我不确定如何实现。
如有任何帮助,我将不胜感激,谢谢!
您需要获取该类型的符号,然后您可以获得该符号的声明:
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>();
// }