You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 18:22:35