# 通知設計書 21-TypeScriptグローバル型警告

## 概要

本ドキュメントは、`@babel/plugin-transform-typescript`プラグインにおける、エクスポートされた識別子がBabelのスコープトラッカーに登録されていない場合に出力されるTypeScriptグローバル型警告の設計について記載する。

### 本通知の処理概要

この通知は、TypeScriptコードをBabelで変換する際に、エクスポートされた識別子がJavaScript値バインディングとしてもTypeScript型宣言としても認識されなかった場合に警告を出力する機能を提供する。

**業務上の目的・背景**：TypeScriptをJavaScriptに変換する過程で、他のプラグインが識別子を注入した際にスコープトラッカーへの登録を忘れると、その識別子が型なのか値なのか判断できない問題が発生する。この警告により、プラグイン開発者が問題を認識し、適切な`scope.registerDeclaration()`呼び出しを追加できるようにする。

**通知の送信タイミング**：`isGlobalType`関数が呼び出され、対象の識別子がスコープにバインディングとして存在せず、かつグローバル型としても登録されていない場合に即座に警告が出力される。

**通知の受信者**：コンソールを監視している開発者、特にBabelプラグインを作成・利用している開発者が対象。この警告は、問題のあるプラグインの作者に向けたものである。

**通知内容の概要**：警告メッセージには、問題となった識別子名、その識別子がJavaScript値として扱われること、および問題の原因が他のプラグインにある可能性と解決方法（`scope.registerDeclaration`の使用）が含まれる。

**期待されるアクション**：プラグイン開発者は、自身のプラグインで識別子を注入している箇所を確認し、`scope.registerDeclaration(declarationPath)`を呼び出してスコープトラッカーに登録するよう修正することが期待される。

## 通知種別

コンソール警告（console.warn）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期 |
| 優先度 | 中 |
| リトライ | 無 |

### 送信先決定ロジック

標準エラー出力（stderr）に対してconsole.warnで出力される。Babelの変換処理を実行しているプロセスのコンソールに表示される。

## 通知テンプレート

### コンソール出力

| 項目 | 内容 |
|-----|------|
| 出力先 | stderr（console.warn経由） |
| 形式 | プレーンテキスト |

### 本文テンプレート

```
The exported identifier "${name}" is not declared in Babel's scope tracker
as a JavaScript value binding, and "@babel/plugin-transform-typescript"
never encountered it as a TypeScript type declaration.
It will be treated as a JavaScript value.

This problem is likely caused by another plugin injecting
"${name}" without registering it in the scope tracker. If you are the author
 of that plugin, please use "scope.registerDeclaration(declarationPath)".
```

### 添付ファイル

| ファイル名 | 形式 | 条件 | 説明 |
|----------|------|------|------|
| なし | - | - | 添付ファイルなし |

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| name | エクスポートされた識別子の名前 | 関数パラメータ | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 処理中 | isGlobalType関数の呼び出し | スコープにバインディングがなく、GLOBAL_TYPESにも登録されていない | TypeScript変換中にエクスポートされた識別子を検査する際 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| スコープにバインディングが存在する | 識別子がJavaScript値として正しく登録されている場合 |
| GLOBAL_TYPESに登録されている | 識別子がTypeScript型として正しく登録されている場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[isGlobalType関数呼び出し] --> B{スコープにバインディングあり?}
    B -->|あり| C[false を返す]
    B -->|なし| D{GLOBAL_TYPESに登録あり?}
    D -->|あり| E[true を返す]
    D -->|なし| F[console.warn で警告出力]
    F --> G[false を返す]
    C --> H[終了]
    E --> H
    G --> H
```

## データベース参照・更新仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| なし | - | データベースは使用しない |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| なし | - | データベースは使用しない |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| なし | - | 警告出力のみでエラーは発生しない |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | なし |
| 1日あたり上限 | なし |

### 配信時間帯

制限なし（変換処理時に同期的に出力）

## セキュリティ考慮事項

- 識別子名がそのまま出力されるが、これはソースコードの一部であり機密情報ではない
- コンソール出力のため、ログファイルに記録される可能性がある

## 備考

- この警告はBabel変換中に発生し、変換結果には影響しない（識別子はJavaScript値として扱われる）
- プラグイン開発者向けのデバッグ情報として機能する

---

## コードリーディングガイド

本通知を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、グローバル型を管理するデータ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | global-types.ts | `packages/babel-plugin-transform-typescript/src/global-types.ts` | GLOBAL_TYPES WeakMapの構造、Scope型との関係を理解する |

**読解のコツ**: `WeakMap<Scope, Set<string>>`という型により、各スコープごとに登録されたグローバル型名のセットを管理していることがわかる。

#### Step 2: エントリーポイントを理解する

警告を出力する関数の実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | global-types.ts | `packages/babel-plugin-transform-typescript/src/global-types.ts` | isGlobalType関数の実装（5-20行目） |

**主要処理フロー**:
1. **行6**: `scope.hasBinding(name)`でスコープ内のバインディングを確認
2. **行7**: `GLOBAL_TYPES.get(scope)!.has(name)`でグローバル型登録を確認
3. **行9-17**: 両方に存在しない場合、console.warnで警告を出力
4. **行19**: falseを返して処理を継続

#### Step 3: 型登録関数を理解する

グローバル型を登録する関数の実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | global-types.ts | `packages/babel-plugin-transform-typescript/src/global-types.ts` | registerGlobalType関数の実装（22-24行目） |

**主要処理フロー**:
- **行23**: `GLOBAL_TYPES.get(programScope)!.add(name)`でグローバル型を登録

### プログラム呼び出し階層図

```
@babel/plugin-transform-typescript
    │
    ├─ isGlobalType(path, name)
    │      ├─ scope.hasBinding(name)
    │      ├─ GLOBAL_TYPES.get(scope).has(name)
    │      └─ console.warn(message)  ← 警告出力
    │
    └─ registerGlobalType(programScope, name)
           └─ GLOBAL_TYPES.get(programScope).add(name)
```

### データフロー図

```
[入力]                    [処理]                         [出力]

NodePath, 識別子名 ───▶ isGlobalType関数 ───▶ boolean（型かどうか）
                              │
                              ▼
                        スコープ/GLOBAL_TYPES確認
                              │
                              ▼
                        未登録の場合 ───▶ console.warn（警告メッセージ）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| global-types.ts | `packages/babel-plugin-transform-typescript/src/global-types.ts` | ソース | グローバル型の管理と警告出力 |
| index.ts | `packages/babel-plugin-transform-typescript/src/index.ts` | ソース | プラグインのエントリーポイント |
