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

如何在评估字符串形式的TypeScript代码时捕获类型错误?

如何运行字符串形式的TypeScript代码并捕获类型错误

要同时实现字符串TS代码的执行和类型错误检测,不能只依赖transpile(它仅做转译不做类型检查),需要利用TypeScript的编译器API完成完整的类型校验,再执行合法代码。

核心思路

  1. 用TypeScript编译器API创建虚拟程序,将字符串代码模拟为文件输入
  2. 提取程序的诊断信息(类型错误、语法错误等)
  3. 无错误时转译代码并执行,有错误则返回错误信息

实现代码示例

import * as ts from 'typescript';

function evaluateTSCode(tsCode: string) {
  // 定义虚拟文件名,TS编译器需要关联文件路径
  const fileName = 'virtual-code.ts';
  
  // 创建编译程序,配置检查规则
  const program = ts.createProgram([fileName], {
    target: ts.ScriptTarget.ESNext,
    strict: true, // 开启严格类型检查,可按需调整
    noEmitOnError: true, // 存在错误时不生成输出代码
  }, {
    // 自定义文件系统实现,让TS读取我们的字符串代码
    readFile: () => tsCode,
    fileExists: () => true,
    getCurrentDirectory: () => '',
    getDirectories: () => [],
    getCanonicalFileName: (file) => file,
    useCaseSensitiveFileNames: () => true,
  });

  // 获取所有预编译诊断信息(包含类型错误)
  const diagnostics = ts.getPreEmitDiagnostics(program);
  
  if (diagnostics.length > 0) {
    // 格式化错误信息
    const errors = diagnostics.map(diagnostic => {
      if (diagnostic.code && diagnostic.messageText) {
        return `TS${diagnostic.code}: ${diagnostic.messageText}`;
      }
      return '未知TypeScript错误';
    });
    return { success: false, errors };
  }

  // 转译合法代码
  const emitResult = program.emit(fileName);
  const transpiledCode = emitResult.outputFiles?.[0]?.text;
  
  if (!transpiledCode) {
    return { success: false, errors: ['代码转译失败'] };
  }

  // 执行转译后的JS代码
  try {
    const result = eval(transpiledCode);
    return { success: true, result };
  } catch (execError) {
    return { success: false, errors: [`运行时错误: ${execError.message}`] };
  }
}

// 测试用例
// 带类型错误的代码
const errorCode = 'const str: string = 123;';
console.log(evaluateTSCode(errorCode));
// 输出: { success: false, errors: ['TS2322: Type 'number' is not assignable to type 'string'] }

// 合法代码
const validCode = 'const str: string = "hello"; return str.length;';
console.log(evaluateTSCode(validCode));
// 输出: { success: true, result: 5 }

关键说明

  • 虚拟文件系统:TypeScript编译器API基于文件系统设计,因此需要实现CompilerHost的必要方法,让编译器能够读取我们的字符串代码。
  • 诊断信息:getPreEmitDiagnostics会返回所有编译前的错误,包括类型不匹配、语法错误等,完全覆盖TS的类型检查能力。
  • 执行风险:使用eval执行动态代码存在安全风险,若处理不可信来源的代码,需额外做安全隔离。
  • 编译选项:可根据需求调整ts.createProgram的第二个参数(编译选项),比如关闭strict、修改target等,适配不同的代码场景。

内容的提问来源于stack exchange,提问作者Gershom Maes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 20:50:20