# 機能設計書 12-defineComponent()

## 概要

本ドキュメントは、TypeScript型推論対応のコンポーネント定義ユーティリティ `defineComponent()` の機能設計書である。

### 本機能の処理概要

`defineComponent()` は、Vueコンポーネントを定義する際にTypeScriptの型推論を有効にするためのユーティリティ関数である。ランタイムでは実質的にno-op（何もしない）に近い実装だが、TypeScriptの型システムと連携して、Props、Emits、Slots、Computed、Methods等の型安全性を提供する。Options APIとComposition APIの両方に対応している。

**業務上の目的・背景**：TypeScriptを使用したVue開発において、コンポーネントのProps、Emits、Setup戻り値等の型推論を自動化し、開発時の型安全性と開発体験（DX）を向上させる。IDEのオートコンプリートやコンパイル時の型エラー検出を実現する。

**機能の利用シーン**：TypeScriptプロジェクトでVueコンポーネントを定義する全ての場面で使用される。特にSFC（Single File Component）の `<script lang="ts">` ブロック内や、TSX/JSXでコンポーネントを定義する場合に必須となる。

**主要な処理内容**：
1. 関数形式（setup関数直接渡し）の場合：setup関数をオブジェクト形式に変換（`{ name, setup }` オブジェクトを構築）
2. オブジェクト形式の場合：渡されたオプションオブジェクトをそのまま返却
3. TypeScript型パラメータを通じた型推論の提供（コンパイル時のみ）

**関連システム・外部連携**：`@vue/runtime-core` パッケージで定義される。コンポーネントの型定義は `component.ts`、Props型は `componentProps.ts`、Emits型は `componentEmits.ts` と連携する。

**権限による制御**：権限による制御は存在しない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 該当なし | - | defineComponent()はコンポーネント定義のユーティリティであり、特定の画面に限定されない |

## 機能種別

型定義ユーティリティ / コンポーネント定義ヘルパー

## 入力仕様

### 入力パラメータ

#### オーバーロード1：setup関数直接渡し

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| setup | (props, ctx) => RenderFunction \| Promise\<RenderFunction\> | Yes | setup関数 | - |
| options | { props?, emits?, slots?, name?, inheritAttrs? } | No | 追加オプション | - |

#### オーバーロード2：オプションオブジェクト

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| options | ComponentOptionsBase & { props?, __typeProps?, __typeEmits?, __typeRefs?, __typeEl? } | Yes | コンポーネントオプション | - |

### 入力データソース

開発者がコンポーネント定義時に直接呼び出す。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| component | DefineComponent / DefineSetupFnComponent | 型付きコンポーネント定義オブジェクト |

### 出力先

呼び出し元に返却。SFCのdefault exportやグローバルコンポーネント登録に使用される。

## 処理フロー

### 処理シーケンス

```
1. 引数が関数かどうか判定
   ├─ 関数の場合：{ name: options.name, ...extraOptions, setup: options } を構築して返却
   └─ オブジェクトの場合：そのまま返却
```

### フローチャート

```mermaid
flowchart TD
    A[defineComponent呼び出し] --> B{第1引数は関数?}
    B -->|Yes| C[extend name, extraOptions, setup]
    B -->|No| D[optionsをそのまま返却]
    C --> E[オブジェクトとして返却]
    D --> E
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-12-01 | 関数形式の変換 | setup関数が直接渡された場合、nameとextraOptionsを含むオブジェクト形式に変換 | isFunction(options)がtrueの場合 |
| BR-12-02 | NO_SIDE_EFFECTS注釈 | Rollupのtree-shakingを有効にするため `@__NO_SIDE_EFFECTS__` と `@__PURE__` アノテーションが付与 | ビルド時 |
| BR-12-03 | 型推論の提供 | `__typeProps`、`__typeEmits`、`__typeRefs`、`__typeEl` は language-tools 用のプライベートプロパティ | TypeScript型推論時 |

### 計算ロジック

ランタイムの計算ロジックは存在しない。型レベルでの複雑な型計算（`DefineComponent` 型、`ResolveProps` 型等）が型パラメータで行われる。

## データベース操作仕様

該当なし。

## エラー処理

### エラーケース一覧

`defineComponent()` 自体にはエラー処理は存在しない。型エラーはTypeScriptコンパイル時に検出される。

### リトライ仕様

該当なし。

## トランザクション仕様

該当なし。

## パフォーマンス要件

- `@__NO_SIDE_EFFECTS__` アノテーションにより、未使用のコンポーネント定義はtree-shakingで除外される。
- ランタイム実装は実質no-opであり、パフォーマンスへの影響は無視できる。

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

特になし。

## 備考

- `DefineComponent` 型は非常に複雑な型パラメータを持ち、Props、Emits、Slots、LocalComponents、Directives、Exposed等の全てを型レベルで追跡する。
- `DefineSetupFnComponent` は関数形式で定義されたコンポーネント専用の簡易型。
- `#8236` のコメントにあるように、Rollupは `extend()` の呼び出しと `options.name` アクセスをside-effectとみなすため、IIFE（即時実行関数式）で `@__PURE__` アノテーションを付けてラップしている。

---

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

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

### 推奨読解順序

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

`DefineComponent` 型と関連する型定義を理解することが最も重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | apiDefineComponent.ts | `packages/runtime-core/src/apiDefineComponent.ts` | DefineComponent型（51-113行目）とDefineSetupFnComponent型（115-137行目） |
| 1-2 | componentProps.ts | `packages/runtime-core/src/componentProps.ts` | ComponentPropsOptions, ExtractPropTypes等の型定義 |
| 1-3 | componentEmits.ts | `packages/runtime-core/src/componentEmits.ts` | EmitsOptions, EmitsToProps等の型定義 |

**読解のコツ**: `DefineComponent` は20以上の型パラメータを持つが、多くにはデフォルト値が設定されている。最も重要なのは `PropsOrPropOptions`（Props定義）と `E`（Emits定義）の2つ。`ResolveProps` 型（44-49行目）がProps型の解決を担当する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | apiDefineComponent.ts | `packages/runtime-core/src/apiDefineComponent.ts` | defineComponent関数のオーバーロード宣言（149-301行目）と実装（305-315行目） |

**主要処理フロー**:
1. **305行目**: 実装関数の開始（`options: unknown, extraOptions?: ComponentOptions`）
2. **309行目**: `isFunction(options)` で関数かどうかを判定
3. **312-313行目**: 関数の場合、`@__PURE__` IIFE内で `extend({ name: options.name }, extraOptions, { setup: options })` を実行
4. **314行目**: オブジェクトの場合、`options` をそのまま返却

#### Step 3: オーバーロードの型推論を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | apiDefineComponent.ts | `packages/runtime-core/src/apiDefineComponent.ts` | オーバーロード1（149-180行目）：setup関数直接渡し |
| 3-2 | apiDefineComponent.ts | `packages/runtime-core/src/apiDefineComponent.ts` | オーバーロード2（183-301行目）：オプションオブジェクト |

**主要処理フロー**:
- **149-164行目**: setup関数 + propsを配列で渡すパターン
- **165-180行目**: setup関数 + propsをオブジェクトで渡すパターン
- **183-301行目**: 完全なオプションオブジェクト渡し。TypeEmits、RuntimeEmitsOptions、ResolvedEmits等の型パラメータ解決を含む

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

```
defineComponent(options, extraOptions?)
    │
    ├─ isFunction(options)
    │      └─ true: extend({ name: options.name }, extraOptions, { setup: options })
    │
    └─ !isFunction(options)
           └─ return options as-is
```

### データフロー図

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

setup関数 ─────────────────▶ extend({name, setup}) ──▶ ComponentOptions
  +extraOptions
                                                         (型: DefineSetupFnComponent)

ComponentOptions ──────────▶ そのまま返却 ──────────▶ ComponentOptions
                                                         (型: DefineComponent)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| apiDefineComponent.ts | `packages/runtime-core/src/apiDefineComponent.ts` | ソース | defineComponentの定義と型オーバーロード |
| component.ts | `packages/runtime-core/src/component.ts` | ソース | Component, SetupContext等のコア型定義 |
| componentOptions.ts | `packages/runtime-core/src/componentOptions.ts` | ソース | ComponentOptionsBase, ComputedOptions, MethodOptions型 |
| componentProps.ts | `packages/runtime-core/src/componentProps.ts` | ソース | ComponentPropsOptions, ExtractPropTypes型 |
| componentEmits.ts | `packages/runtime-core/src/componentEmits.ts` | ソース | EmitsOptions, EmitsToProps型 |
| componentSlots.ts | `packages/runtime-core/src/componentSlots.ts` | ソース | SlotsType型定義 |
| componentPublicInstance.ts | `packages/runtime-core/src/componentPublicInstance.ts` | ソース | ComponentPublicInstanceConstructor型 |
| apiSetupHelpers.ts | `packages/runtime-core/src/apiSetupHelpers.ts` | ソース | ComponentTypeEmits型 |
