1. 前言

TypeScript 在游戏开发领域的应用日益广泛,Cocos Creator、Egret、LayaAir 等引擎均将其作为主要开发语言,PuerTS 方案也让 Unity 开发者能够以 TypeScript 编写逻辑。对于具备 C# 或 C++ 背景的开发者而言,TypeScript 的类型系统并不陌生,但其运行于 JavaScript 引擎之上,编译模型与静态编译语言存在本质差异。本文将聚焦环境搭建与编译流程,建立对 TypeScript 工具链的准确认知。

2. 运行环境安装

TypeScript 编译器基于 Node.js 运行,需先安装 Node.js(建议 LTS 版本)。安装完成后,使用 npm 全局安装 TypeScript:

npm install -g typescript

验证安装:

tsc --version

tsc(TypeScript Compiler)是核心命令行工具,负责将 .ts 文件编译为 .js 文件。

3. 项目初始化与配置文件

在项目根目录执行以下命令生成配置文件:

tsc --init

该命令创建 tsconfig.json,包含编译器选项。关键配置项如下:

配置项 说明 推荐值
target 输出 JavaScript 版本 "ES2020"(现代引擎普遍支持)
module 模块系统 "ESNext"(配合引擎的模块加载)
strict 启用严格类型检查 true(强烈建议)
outDir 编译输出目录 "./dist""./build"
rootDir 源码根目录 "./src"
sourceMap 生成 Source Map true(调试必需)
noImplicitAny 禁止隐式 any true
strictNullChecks 严格空值检查 true

典型 tsconfig.json 示例:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "strict": true,
    "outDir": "./dist",
    "rootDir": "./src",
    "sourceMap": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "esModuleInterop": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}

4. 第一个 TypeScript 程序

创建 src/main.ts

function greet(name: string): void {
    console.log(`Hello, ${name}`);
}

let playerName: string = "Warrior";
greet(playerName);

执行编译:

tsc

编译器读取 tsconfig.json,将 src 下的 .ts 文件编译输出至 dist 目录。生成 dist/main.js 内容如下:

function greet(name) {
    console.log(`Hello, ${name}`);
}
let playerName = "Warrior";
greet(playerName);

观察可知:

  • 类型注解 : string: void 已被移除。
  • 模板字符串被原样保留(ES2020 目标下)。
  • 代码逻辑完全一致,未引入任何运行时辅助代码。

5. 编译模式:单次编译与监听模式

开发过程中可启用监听模式,文件变更时自动重新编译:

tsc --watch

在 Cocos Creator 等引擎项目中,编辑器通常已集成 TypeScript 编译流程,开发者无需手动执行命令,但理解底层机制有助于排查编译异常。

6. 类型擦除与运行时开销

TypeScript 的核心设计原则之一是 类型擦除:所有类型信息在编译阶段被完全移除,输出的 JavaScript 代码不含任何类型检查逻辑。这意味着:

  1. 运行时性能与手写 JavaScript 一致——游戏帧循环中高频调用的 TypeScript 函数不会因类型注解产生额外开销。
  2. 类型系统仅作用于开发阶段——编译通过不代表运行时无类型错误,若代码中使用了 any 绕过检查,或与无类型的 JavaScript 库交互,仍可能在运行时抛出异常。
  3. 类型定义不影响代码体积——类型注解与接口定义不会出现在最终产物中。

以下对比示例可清晰说明类型擦除:

TypeScript 源码:

interface DamageInfo {
    amount: number;
    source: string;
}

function applyDamage(target: { health: number }, info: DamageInfo): void {
    target.health -= info.amount;
}

编译后 JavaScript:

function applyDamage(target, info) {
    target.health -= info.amount;
}

DamageInfo 接口完全消失,函数签名中的类型注解被移除。这一特性要求开发者在与外部数据(如网络包、JSON 配置)交互时,仍需进行防御性校验。

7. 与 C# 编译模型的对比

维度 C# (Unity IL2CPP) TypeScript
编译目标 IL → C++ → 原生机器码 JavaScript 源码
类型存在阶段 运行时保留(通过反射可访问) 仅编译时存在
类型错误检测 编译期 + 运行期(类型强校验) 编译期为主,运行期依赖 JavaScript 动态类型
泛型实现 运行时具象化(值类型专用化) 编译时擦除(仅类型检查)

理解这一差异有助于避免将 C# 的编程惯性直接迁移至 TypeScript。例如,TypeScript 中无法通过 typeof 获取接口信息,无法进行运行时类型判断。

8. 游戏开发场景:为 Cocos Creator 配置独立 TypeScript 环境

若使用 Cocos Creator 3.x,引擎已内置 TypeScript 支持,开发者无需手动配置。但在以下场景中,独立配置仍有价值:

  • 编写与引擎无关的工具链(如 Excel 导表工具、资源检查脚本)。
  • 为 PuerTS 项目编写纯 TypeScript 逻辑层。

以 PuerTS 为例,项目结构建议如下:

project/
├── TsProject/
│   ├── src/            # TypeScript 源码
│   ├── dist/           # 编译输出
│   ├── tsconfig.json
│   └── package.json
└── Assets/             # Unity 资源目录

配置 tsconfig.json 时,需注意:

{
  "compilerOptions": {
    "target": "ES2015",
    "module": "CommonJS",          // PuerTS 默认使用 CommonJS 加载
    "outDir": "../Assets/StreamingAssets/JS",
    "rootDir": "./src",
    "strict": true,
    "types": ["csharp"]            // 引入 PuerTS 的 C# 类型声明
  }
}

编译命令:

cd TsProject
tsc --watch

Unity 运行时将加载 StreamingAssets/JS 中的 JavaScript 文件执行。

9. 常见问题排查

Q1:tsc 命令报错“无法加载文件…禁止运行脚本”

Windows PowerShell 执行策略限制。使用 Set-ExecutionPolicy RemoteSigned -Scope CurrentUser 或改用 CMD。

Q2:编译后代码中的 import 语句在浏览器/引擎中报错

module 配置与运行环境不匹配。若环境不支持 ES Module,需改用 CommonJSUMD,或使用打包工具(如 Webpack、Rollup)。

Q3:类型错误未在编辑器中显示

确保编辑器的 TypeScript 语言服务已启用,且使用项目本地的 TypeScript 版本(npm install typescript --save-dev)。

10. 本篇小结

  • TypeScript 通过 tsc 编译器将类型注解代码转换为纯 JavaScript,无运行时开销。
  • tsconfig.json 控制编译行为,严格模式建议开启。
  • 类型擦除机制要求开发者明确区分编译时安全与运行时安全。
  • 理解编译模型有助于在游戏项目中正确配置工具链。

下一篇将深入 TypeScript 的基础类型系统,涵盖字面量类型、联合类型及其在游戏状态管理中的应用。


参考资源

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐