使用TypeScript Compiler API序列化导出类型时遇未定义错误求助
解决TypeScript Compiler API中getSymbolAtLocation返回undefined的问题
你遇到的问题是因为ts.createProgram默认会从磁盘读取文件,但你创建的sourceFile只存在于内存中,导致程序无法正确关联到这个源文件,所以typeChecker.getSymbolAtLocation(sourceFile)返回了undefined。
以下是修正后的代码,通过自定义CompilerHost让程序读取内存中的源文件,从而正确获取导出对象的类型信息:
const ts = require('typescript'); const code = ` type Config = { hello: string; }; const config: Config = { hello: "world", }; export default config; `; // 创建内存中的源文件 const sourceFileName = 'myModule.ts'; const sourceFile = ts.createSourceFile(sourceFileName, code, ts.ScriptTarget.ESNext); // 自定义CompilerHost,从内存读取文件 const host = { getSourceFile: (fileName) => fileName === sourceFileName ? sourceFile : undefined, getDefaultLibFileName: () => ts.getDefaultLibFilePath({ target: ts.ScriptTarget.ESNext }), writeFile: () => {}, getCurrentDirectory: () => '', getDirectories: () => [], getCanonicalFileName: (fileName) => fileName, useCaseSensitiveFileNames: () => true, getNewLine: () => '\n', readFile: () => undefined, fileExists: (fileName) => fileName === sourceFileName || fileName === ts.getDefaultLibFilePath({ target: ts.ScriptTarget.ESNext }) }; // 使用自定义Host创建Program const program = ts.createProgram([sourceFileName], {}, host); const typeChecker = program.getTypeChecker(); // 获取模块的符号 const sourceFileSymbol = program.getSourceFile(sourceFileName) && typeChecker.getSymbolAtLocation(program.getSourceFile(sourceFileName)!); if (!sourceFileSymbol) { throw new Error('Failed to get source file symbol'); } // 获取模块导出 const exports = typeChecker.getExportsOfModule(sourceFileSymbol); // 找到默认导出 const defaultExport = exports.find(exp => exp.name === 'default'); if (defaultExport) { // 获取默认导出的类型 const type = typeChecker.getTypeOfSymbolAtLocation(defaultExport, sourceFile); // 输出类型结构 console.log(typeChecker.typeToString(type)); // 遍历类型属性获取细节 const properties = type.getProperties(); properties.forEach(prop => { const propType = typeChecker.getTypeOfSymbolAtLocation(prop, sourceFile); console.log(`${prop.name}: ${typeChecker.typeToString(propType)}`); }); }
关键修改说明
- 自定义
CompilerHost:覆盖文件读取相关方法,让程序直接从内存获取你创建的源文件,无需依赖磁盘文件 - 正确关联源文件:通过自定义Host确保
createProgram能识别到内存中的文件,从而成功获取源文件符号 - 提取类型信息:找到默认导出符号后,使用
getTypeOfSymbolAtLocation获取其类型,再通过typeToString或遍历属性来序列化类型细节
内容的提问来源于stack exchange,提问作者Firanolfind
相关产品推荐
相关产品推荐

