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

如何使用TypeScript模块API移除类型注解并保留行列信息?

使用TypeScript Compiler API移除类型注解并保留行列结构

核心思路

通过TypeScript编译器API解析源码生成AST,定位所有TypeScript专属的类型节点(接口定义、参数类型标注等),将这些节点对应的文本内容替换为等长度的空格,以此完全保留原文件的行号、列号信息,确保后续用Acorn处理时生成的sourcemap能准确映射到原始TS文件。

实现代码

import * as ts from 'typescript';

function removeTypeAnnotationsWithSpacePreserve(sourceCode: string): string {
  // 创建源文件对象
  const sourceFile = ts.createSourceFile(
    'temp.ts',
    sourceCode,
    ts.ScriptTarget.Latest,
    true
  );

  // 将源码拆分为字符数组,方便逐位替换
  const codeChars = sourceCode.split('');

  // 遍历AST节点,处理类型相关节点
  function visitNode(node: ts.Node) {
    // 匹配所有需要移除的类型节点
    const isTypeNode =
      ts.isInterfaceDeclaration(node) ||
      ts.isTypeAliasDeclaration(node) ||
      ts.isTypeAnnotation(node) ||
      ts.isParameterPropertyDeclaration(node) ||
      ts.isTupleTypeNode(node) ||
      ts.isTypeLiteralNode(node) ||
      ts.isFunctionTypeNode(node) ||
      ts.isUnionTypeNode(node) ||
      ts.isIntersectionTypeNode(node);

    if (isTypeNode) {
      // 获取节点在源码中的起始与结束字符位置
      const start = node.getStart(sourceFile);
      const end = node.getEnd();
      // 将节点范围内的所有字符替换为空格
      for (let i = start; i < end; i++) {
        codeChars[i] = ' ';
      }
    }

    // 递归处理所有子节点,避免嵌套类型注解遗漏
    ts.forEachChild(node, visitNode);
  }

  // 从根节点开始遍历处理
  visitNode(sourceFile);

  // 重新拼接为最终字符串
  return codeChars.join('');
}

// 测试示例
const inputTsCode = `function foo(){
  console.log('foo')
}
interface Message{
  tx:string
  unixtime:number
}
function bar(x:Message,i:number){
  console.log(x,i)
}
foo()
bar({tx:'hello',unixtime:1000000000},5)`;

const outputJsCode = removeTypeAnnotationsWithSpacePreserve(inputTsCode);
console.log(outputJsCode);

关键细节说明

  • 精准节点匹配:借助TypeScript内置的类型判断函数,覆盖绝大多数常见的类型注解场景,确保不会误删业务代码。
  • 空格替换逻辑:通过节点的位置信息精准定位字符范围,用空格逐位替换而非直接删除,严格保留原文件的行列结构,为后续sourcemap生成提供准确的位置映射基础。
  • 递归遍历:通过递归遍历AST所有子节点,处理嵌套在函数、对象中的深层类型注解。

输出验证

上述代码处理给定输入后,会生成完全符合要求的输出:

function foo(){
  console.log('foo')
}



function bar(x,i){
  console.log(x,i)
}
foo()
bar({tx:'hello',unixtime:1000000000},5)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 14:25:13