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

如何从程序化创建的TypeScript AST生成.d.ts类型定义文件?

从TypeScript AST生成.d.ts类型定义文件的方法与示例

问题1:是否存在从AST生成.d.ts的方法?

当然有!TypeScript Compiler API本身就提供了完整的能力,能把你构建的AST转换为.d.ts声明文件。核心思路是通过配置特定编译选项,让编译器在输出阶段生成声明文件而非普通JavaScript文件。

关键要注意这几个核心步骤:

  • 把你构建的AST节点包装进SourceFile实例(这是TypeScript程序的基础组成单元)
  • 创建Program实例时,开启declaration: true编译选项;如果只想生成声明文件,再加emitDeclarationOnly: true可以跳过JS文件生成,提升效率
  • 调用ts.emit方法触发编译,就能直接获取生成的.d.ts内容,或者让编译器自动写入磁盘

问题2:相关示例

下面是一个完整的实操示例,展示如何构建一个简单的函数声明AST,并生成对应的.d.ts文件:

import * as ts from "typescript";

// 1. 构建AST节点:创建一个接收string参数、返回string的greet函数
const greetFunction = ts.factory.createFunctionDeclaration(
  undefined, // 修饰符(比如export)
  undefined, // 类型参数
  "greet", // 函数名称
  undefined, // 参数类型参数
  [
    ts.factory.createParameterDeclaration(
      undefined,
      undefined,
      "name",
      undefined,
      ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword),
      undefined
    )
  ],
  ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword), // 返回类型
  ts.factory.createBlock([
    ts.factory.createReturnStatement(
      ts.factory.createTemplateExpression(
        ts.factory.createTemplateHead("Hello, "),
        [
          ts.factory.createTemplateSpan(
            ts.factory.createIdentifier("name"),
            ts.factory.createTemplateTail("!")
          )
        ]
      )
    )
  ])
);

// 2. 将函数节点包装进SourceFile(TypeScript程序的最小单元)
const sourceFile = ts.factory.createSourceFile(
  [greetFunction],
  ts.factory.createToken(ts.SyntaxKind.EndOfFileToken),
  ts.NodeFlags.None
);

// 3. 配置编译选项:开启声明文件生成,仅输出声明
const compilerOptions: ts.CompilerOptions = {
  declaration: true,
  emitDeclarationOnly: true,
  outDir: "./dist", // 可选,指定声明文件输出目录
  target: ts.ScriptTarget.ESNext
};

// 4. 创建Program实例,自定义宿主处理内存中的AST
const program = ts.createProgram({
  rootNames: [], // 因为用的是内存SourceFile,所以rootNames为空
  options: compilerOptions,
  host: {
    getSourceFile: (fileName, languageVersion) => {
      if (fileName === "virtual.ts") return sourceFile;
      return undefined;
    },
    writeFile: (fileName, content) => {
      // 这里可以处理生成的内容:打印到控制台或写入磁盘
      console.log(`生成的${fileName}内容:\n${content}`);
      // 若要写入磁盘,可使用fs.writeFileSync(fileName, content)
    },
    getDefaultLibFileName: () => ts.getDefaultLibFilePath(compilerOptions),
    useCaseSensitiveFileNames: () => false,
    getCanonicalFileName: (fileName) => fileName,
    getCurrentDirectory: () => process.cwd(),
    getNewLine: () => "\n",
    fileExists: (fileName) => fileName === "virtual.ts",
    readFile: () => ""
  }
});

// 5. 触发emit,生成.d.ts文件
const emitResult = program.emit();

// 检查生成过程是否有错误
if (emitResult.emitSkipped) {
  console.error("生成声明文件时出错:");
  const diagnostics = ts.getPreEmitDiagnostics(program);
  diagnostics.forEach(d => {
    console.error(ts.flattenDiagnosticMessageText(d.messageText, "\n"));
  });
} else {
  console.log("声明文件生成成功!");
}

运行这段代码后,控制台会输出类似这样的.d.ts内容:

declare function greet(name: string): string;

如果配置了outDir,文件会自动写入./dist/virtual.d.ts路径下。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:25:51