这是TypeScript Compiler API系列的第三篇文章
学习如何使用Compiler API将TypeScript转译为JavaScript
现在让我们开始探索真正的Compiler API吧💃!
如第1章所述,编译器API功能丰富,其中一项核心功能就是将TypeScript代码直接转译为JavaScript代码。本章将介绍如何通过API实现这一过程。
准备工作
首先在电脑上创建实验目录。确保已全局安装npm,然后执行命令:
mkdir ts-compiler-api-fun(创建目录)cd ts-compiler-api-fun(进入目录)
Windows用户请注意命令差异。进入空目录后:
-
运行
npm init初始化项目 -
安装依赖:
- TypeScript:
npm install typescript(或yarn add typescript) - NodeJS类型定义:
npm install --save-dev @types/node
- TypeScript:
代码转译
-
创建TypeScript文件:
- 执行
touch fun.ts - 用VSCode等编辑器打开:
code fun.ts
- 执行
-
编写基础TS代码:
function hello(world: string): boolean {
return world === "world"
}
- 创建编译脚本文件
index.mjs,内容如下:
import ts from "typescript"
import fs from "fs"
const source = fs.readFileSync("./fun.ts", { encoding: "utf8" })
const result = ts.transpileModule(source, {
compilerOptions: { module: ts.ModuleKind.ESNext }
})
fs.writeFileSync("fun.js", result.outputText)
-
在
package.json的scripts中添加:"compile": "node index.mjs" -
运行
npm run compile后,将生成:
function hello(world) {
return world === "world"
}
成功移除了类型注解!恭喜你首次直接使用Compiler API完成了编译🎉!
编译器选项
调用ts.transpileModule()时传入的compilerOptions参数至关重要。目前编译器提供100+个配置选项,这些选项与tsconfig.json和tsc命令行工具完全兼容。
完整选项列表参考TypeScript官方文档。
使用ts.createProgram()
之前我们通过Node的fs模块处理文件,现在改用Compiler API自带的文件处理功能,这对大批量文件更高效。
基本用法:
const program = ts.createProgram(fileNames, compilerOptions)
const result = program.emit()
程序会自动生成对应的.js文件。
优化后的完整示例:
import ts from "typescript"
const program = ts.createProgram(["./fun.ts"], {
module: ts.ModuleKind.ESNext
})
const result = program.emit()
代码更简洁,接下来我们看看如何获取诊断信息。
诊断信息
诊断信息能帮助开发者定位代码问题。让我们修改示例代码制造一个类型错误:
function hello(world: string): bolean { // 故意拼错boolean
return world === "world"
}
增强诊断信息输出:
// 合并编译前和编译后的诊断信息
const diagnostics = ts.getPreEmitDiagnostics(program).concat(result.diagnostics)
// 格式化输出
diagnostics.forEach((diagnostic) => {
if (diagnostic.file) {
const { line, character } = ts.getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start)
const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n")
console.log(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`)
} else {
console.log(ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n"))
}
})
运行后将看到智能提示:
fun.ts (1,32): Cannot find name 'bolean'. Did you mean 'boolean'?
再测试noImplicitAny选项:
const program = ts.createProgram(["fun.ts"], {
module: ts.ModuleKind.ESNext,
noImplicitAny: true
})
当参数没有类型注解时,会提示:
fun.ts (1,16): Parameter 'world' implicitly has an 'any' type.
本章总结
本节我们学会了:
- 使用Compiler API转译TS代码
- 处理诊断信息
- 通过编译器选项控制代码检查
这些知识将为下一章的TypeScript代码解析打下基础。