---
name: typescript_module_patterns.aicomponent
description: TypeScript 项目中资源导入模式、模块声明模板和常见编译错误的修复指南。帮助 Agent 在第一次就写出正确的 import 代码，避免 TS 编译报错。
triggers: TypeScript 编译错误,TS2580,TS2300,TS2307,Cannot find module,require,import 资源,模块声明,globals.d.ts
---

# TypeScript 模块模式与错误修复指南

## 说明

在 Phaser + Webpack + TypeScript 项目中，资源导入是最常见的出错点。本 skill 提供：

1. **标准模块声明模板**（`globals.d.ts`）
2. **资源导入的正确方式**（ES import vs require vs 路径字符串）
3. **常见 TS 错误→修复映射表**（遇到错误直接查表）

## Scaffold

| 目标路径 | 来源 | 说明 |
|---------|-----|------|
| `globals.d.ts` | `ref/globals.d.ts` | 所有资源类型的模块声明 |

## 模块声明模板（globals.d.ts）

```typescript
// 图片资源
declare module "*.png" {
  const src: string;
  export default src;
}
declare module "*.webp" {
  const src: string;
  export default src;
}
declare module "*.jpg" {
  const src: string;
  export default src;
}
declare module "*.svg" {
  const src: string;
  export default src;
}

// 音频资源
declare module "*.mp3" {
  const src: string;
  export default src;
}
declare module "*.ogg" {
  const src: string;
  export default src;
}
declare module "*.wav" {
  const src: string;
  export default src;
}

// JSON（TypeScript 内置支持，但需要 tsconfig 中 resolveJsonModule: true）
// declare module "*.json" { ... }  // 通常不需要
```

## 资源导入正确方式

### ✅ 正确：ES import（推荐）

```typescript
import carImage from "assets/images/car.webp";
import clickSfx from "assets/sounds/click.mp3";
import levelData from "./levels/level1.json";

// 在 Phaser 中使用
this.load.image("car", carImage);     // carImage 是 webpack 生成的文件 URL
this.load.audio("click", clickSfx);
```

**原理**：webpack 的 `asset/resource` 规则处理这些文件，输出到 dist/ 并返回最终 URL 字符串。TypeScript 通过 `globals.d.ts` 中的模块声明知道 `import *.webp` 返回 `string` 类型。

### ❌ 错误：require（ESM 项目不可用）

```typescript
// ❌ 报错：TS2580: Cannot find name 'require'
this.load.image("car", require("assets/images/car.webp"));
```

**原因**：项目 tsconfig 配置为 `module: "esnext"`，不支持 CommonJS 的 `require`。

**修复**：改为 ES import：
```typescript
import carImage from "assets/images/car.webp";
this.load.image("car", carImage);
```

### ❌ 错误：路径字符串（webpack 无法追踪）

```typescript
// ❌ 运行时 404：webpack 不会打包这个文件
this.load.image("car", "./assets/images/car.webp");
```

**原因**：字符串路径不会被 webpack 的 module 规则处理，文件不会被复制到 dist/。

## 常见错误→修复映射表

| TS 错误码 | 错误信息 | 原因 | 修复 |
|-----------|---------|------|------|
| **TS2580** | `Cannot find name 'require'` | ESM 项目用了 CJS 语法 | 改为 `import x from "..."` |
| **TS2300** | `Duplicate identifier 'xxx'` | 同一变量名被 import 两次 | 删除重复的 import 行 |
| **TS2307** | `Cannot find module '*.webp'` | 缺少模块声明 | `globals.d.ts` 加 `declare module "*.webp"` |
| **TS2307** | `Cannot find module './Foo'` | 文件路径错误或缺少 | 检查文件是否存在，大小写是否一致 |
| **TS7016** | `Could not find declaration file for module 'xxx'` | 第三方库缺少类型 | 安装 `@types/xxx` 或创建 `.d.ts` |
| **TS1259** | `Module can only be default-imported using esModuleInterop` | 导入 CJS 模块格式不对 | tsconfig 加 `"esModuleInterop": true` |
| **TS2339** | `Property 'xxx' does not exist on type` | 类型不匹配 | 添加类型断言 `as any` 或修正类型 |
| **TS2345** | `Argument of type 'X' is not assignable to 'Y'` | 类型不兼容 | 检查接口定义，或用 `as any` 临时绕过 |

## import 规范

### 导入顺序（推荐）

```typescript
// 1. 第三方库
import * as Phaser from "phaser";
import { Scene } from "phaser";

// 2. 内部模块（绝对路径或 alias）
import { GameConfig } from "../GameConfig";
import { computeUiLayout } from "../utils/UiLayout";

// 3. 资源文件（放最后）
import carImage from "assets/images/car.webp";
import clickSfx from "assets/sounds/click.mp3";
```

### 避免重复 import

每个模块/资源只 import 一次，放在文件顶部。如果需要在多处使用，import 一次后传参：

```typescript
// ✅ 正确：顶部 import 一次
import carImage from "assets/images/car.webp";

// 然后在代码中多次引用变量 carImage
this.load.image("car", carImage);
```

```typescript
// ❌ 错误：多次 import 同一模块
import carImage from "assets/images/car.webp";
import carImage from "assets/images/car.webp"; // TS2300: Duplicate identifier
```

## tsconfig.json 关键配置

```json
{
  "compilerOptions": {
    "module": "esnext",
    "moduleResolution": "bundler",
    "esModuleInterop": true,
    "resolveJsonModule": true,
    "allowSyntheticDefaultImports": true,
    "paths": {
      "assets/*": ["./assets/*"]
    }
  }
}
```

| 配置项 | 作用 | 缺少的后果 |
|--------|------|-----------|
| `module: "esnext"` | 使用 ES module 语法 | 无法用 `import` |
| `moduleResolution: "bundler"` | webpack 兼容的模块解析 | 路径解析失败 |
| `esModuleInterop: true` | 允许 `import x from "cjs-lib"` | CJS 库导入报错 |
| `resolveJsonModule: true` | 允许 `import data from "./x.json"` | JSON import 报错 |
| `paths.assets/*` | alias 路径映射 | `import from "assets/..."` TS 报错 |

## Recipe

| 决策 | 原因 |
|------|------|
| **独立知识 skill** | TS 资源导入报错是高频问题，与引擎 skill 分离后 Agent 可按需加载，不污染 phaser/threejs skill 的主流程 |
| **错误码→修复映射表** | Agent 遇到 TS 编译报错时可直接查表定位修复，避免反复试错 |
| **偏向文档而非 Scaffold** | 模块声明本质是一份固定模板；核心价值在于教 Agent 正确的 import 模式，比直接写文件更重要 |

## Adapter

- **Role**: `tsModulePatterns` — TypeScript 资源导入规范与错误修复知识库
- **Provides**: `globals.d.ts` 模块声明模板、正确 import 模式示例、TS 错误码→修复映射表
- **Requires**: `webpack_build.aicomponent`（alias 需与 tsconfig `paths` 一致）、`phaser.aicomponent`（提供 tsconfig.json 骨架）
- **Consumed by**: 所有在 Webpack + TypeScript 项目中导入图片/音频资源时遇到 TS 报错的 skill
- **Integration point**: 根目录 `globals.d.ts` —— 所有资源 `import` 的类型声明来源

## Imports

- `webpack_build.aicomponent`（配合使用：webpack alias 与 tsconfig paths 需一致）
- `phaser.aicomponent`（配合使用：提供 tsconfig.json 骨架）

## Skill Definition

```yaml
tools:
  - read_file
  - write_file
inputs:
  - source: ref/globals.d.ts
outputs:
  - typeDeclaration: globals.d.ts module declarations
  - patterns: correct import patterns for webpack + TypeScript
  - errorFixMap: TS error code → fix mapping
```
