使用TypeScript编译器API获取标识符类型时输出any的问题排查
解决TypeScript API获取变量类型返回any的问题
给定如下TypeScript代码:
function foo (s: string) { console.log(s) }
希望通过TypeScript API获取console.log(s)中s的类型,期望结果为string,但现有代码返回any。
问题原因
- 原代码创建
Program时,指定了磁盘文件路径test.ts,但实际代码是内存中的字符串,导致Program无法加载正确的源文件,类型检查器无法解析变量的类型绑定。 - 未正确关联内存中的
SourceFile到Program,使得类型检查器无法获取函数参数的类型信息。
修正后的代码
const ts = require("typescript"); const sourceCode = ` function foo(s: string) { console.log(s) } `; // 创建内存源文件 const sourceFile = ts.createSourceFile( "test.ts", sourceCode, ts.ScriptTarget.Latest, true ); // 自定义CompilerHost,从内存读取源文件 const host = ts.createCompilerHost({}); host.getSourceFile = (fileName, languageVersion) => { return fileName === "test.ts" ? sourceFile : ts.createSourceFile(fileName, "", languageVersion); }; // 创建包含内存源文件的Program const program = ts.createProgram(["test.ts"], {}, host); const typeChecker = program.getTypeChecker(); // 定位到目标标识符s const functionDeclaration = sourceFile.statements.find( stmt => ts.isFunctionDeclaration(stmt) && stmt.name?.text === "foo" ) as ts.FunctionDeclaration; const logCall = (functionDeclaration.body.statements[0] as ts.ExpressionStatement).expression as ts.CallExpression; const targetIdentifier = logCall.arguments[0] as ts.Identifier; // 获取并打印类型 const type = typeChecker.getTypeAtLocation(targetIdentifier); console.log(typeChecker.typeToString(type)); // 输出:string
关键修改说明
- 自定义CompilerHost:重写
getSourceFile方法,让Program能够读取内存中创建的源文件,避免依赖磁盘文件。 - 关联Program与SourceFile:通过自定义Host将内存代码注入
Program,确保类型检查器可以解析完整的类型信息。 - 精准节点定位:使用TypeScript类型守卫(如
ts.isFunctionDeclaration)确保节点类型正确,避免运行时错误。 - 使用getTypeAtLocation:直接获取目标节点的类型,相比
getTypeOfSymbolAtLocation更适配当前场景。
内容的提问来源于stack exchange,提问作者Patrick McElhaney
相关产品推荐
相关产品推荐

