{"id":"1ebbd035-79a3-4476-981e-e79b6898985f","shortId":"fdys2s","kind":"skill","title":"functional-ts-review-ja","tagline":"サーバーサイドTypeScriptコードを関数型ドメインモデリング原則に照らしてレビューする。`functional-ts-ja` スキルと同じナレッジを参照し、Discriminated Union、Companion Object、Branded Types、不変性、ファイル構成、純粋関数による状態遷移、網羅性チェック、Result型によるエラーハンドリング、境界の防御（スキーマバリデーション・`as` 禁止・PII 保護）、宣言的スタイル、型安全なテストデータをチェックする。","description":"# Functional TypeScript Code Review\n\n`functional-ts-ja` スキルが定める関数型ドメインモデリング原則に照らしてサーバーサイドTypeScriptコードをレビューする。本スキルは `functional-ts-ja` と**同じナレッジを参照する**。各チェック項目はあちらの章と1対1で対応し、根拠の所在を相対リンクで明示する。\n\n## レビュー手順\n\n1. **原則ナレッジを先に読み込む。** コード閲覧の前に以下を読み、指摘で正典の原則を引けるようにする:\n   - [`../functional-ts-ja/SKILL.md`](../functional-ts-ja/SKILL.md) — 原則のインデックス\n   - [`../functional-ts-ja/error-handling.md`](../functional-ts-ja/error-handling.md)\n   - [`../functional-ts-ja/boundary-defense.md`](../functional-ts-ja/boundary-defense.md)\n   - [`../functional-ts-ja/state-modeling.md`](../functional-ts-ja/state-modeling.md)\n   - プロジェクトの `package.json` に応じたバリデーションライブラリガイド ([`../functional-ts-ja/validation-libraries/`](../functional-ts-ja/validation-libraries/) 配下の `zod.md` / `valibot.md` / `arktype.md`)\n   - プロジェクトの `package.json` に応じた Result ライブラリガイド ([`../functional-ts-ja/result-libraries/`](../functional-ts-ja/result-libraries/) 配下の `neverthrow.md` / `byethrow.md` / `fp-ts.md` / `option-t.md`)\n2. レビュー対象のファイルを読む。\n3. 以下のチェック項目を、原則の順序（`functional-ts-ja/SKILL.md` の章立てと一致）でスキャンする。\n4. 違反を発見した場合、原則・理由・修正案を添えて指摘する。\n5. 違反ではないが改善余地がある場合は提案として伝える。\n\n## チェック項目\n\nチェック項目は [`../functional-ts-ja/SKILL.md`](../functional-ts-ja/SKILL.md) の構造をそのまま反映する。各項目は正典の章へリンクする。\n\n### 1. 型によるドメインモデリング\n\n#### 1.1 ドメイン状態を Discriminated Union でモデリングしているか\n\n参照: [`../functional-ts-ja/SKILL.md` §1「Discriminated Unionで状態を表現する」](../functional-ts-ja/SKILL.md)\n\n兆候: 多数の optional プロパティと `string` の状態フィールドを持つ単一の型（例: `{ state: string; driverId?: string; startTime?: Date }`）。状態ごとに型を分けて union にし、状態固有プロパティを必須にするよう提案する。\n\n#### 1.2 discriminant が `kind` で統一されているか\n\n参照: [`../functional-ts-ja/SKILL.md` §1「discriminantは `kind` で統一する」](../functional-ts-ja/SKILL.md)\n\n兆候: `type`, `status`, `state`, `_tag` など `kind` 以外の discriminant 名。コードベースの一貫性のため `kind` への変更を提案する。\n\n#### 1.3 ドメインモデルに class を使っていないか\n\n参照: [`../functional-ts-ja/SKILL.md` §1「Discriminated Unionで状態を表現する」](../functional-ts-ja/SKILL.md) および Companion Object パターン。\n\nドメインエンティティ・値オブジェクトの定義に `class` を使っている場合、Discriminated Union + Companion Object パターンへの変更を提案する。外部ライブラリが class 継承を要求する場合は正当な逸脱。\n\n#### 1.4 Companion Object パターンに従っているか\n\n参照: [`../functional-ts-ja/SKILL.md` §1「Companion Object パターン」](../functional-ts-ja/SKILL.md)\n\n以下を確認する:\n- 型に関連する操作が、型と同名の `const` に集約されているか。\n- Branded Type のバリデーションスキーマが、スタンドアロンの `XxxSchema` ではなく companion object の `.schema` プロパティとして公開されているか。\n- companion object に置くべきドメインロジックが、`xxxAssignDriver` のような独立関数として散在していないか。\n\n#### 1.5 ドメイン型に `interface` を使っていないか\n\n参照: [`../functional-ts-ja/SKILL.md` §1「`type` を使う（`interface` ではなく）」](../functional-ts-ja/SKILL.md)\n\ndeclaration merging により型の形状が暗黙に変わる危険がある。ドメイン型は `type` で定義する。`interface` はライブラリの型拡張（augmentation）の場合のみ許容。\n\n#### 1.6 型定義内でメソッド記法を使っていないか\n\n参照: [`../functional-ts-ja/SKILL.md` §1「関数プロパティ記法を使う（メソッド記法ではなく）」](../functional-ts-ja/SKILL.md)\n\nメソッド記法（`save(task: Task): Promise<void>`）はパラメータが bivariant になり、依存注入時に狭い型の実装（`save(task: DoingTask): …`）が型チェックを通過する。関数プロパティ記法（`save: (task: Task) => Promise<void>`）への変更を提案する。\n\n#### 1.7 意味の異なるプリミティブに Branded Types が適用されているか\n\n参照: [`../functional-ts-ja/SKILL.md` §1「Branded Typesで意味を区別する」](../functional-ts-ja/SKILL.md)。プロジェクトのバリデーションライブラリガイド ([`../functional-ts-ja/validation-libraries/`](../functional-ts-ja/validation-libraries/)) も参照。\n\n兆候: ID や意味の異なる値（`UserId`, `OrderId`, `Email`, 金額など）が素の `string` / `number` で扱われている。バリデーションライブラリがある場合はそのブランド機能で（`as` キャスト不要）、ない場合は `unique symbol` パターンで定義されているかを確認する。\n\n#### 1.8 ドメインオブジェクトが `Readonly<>` か\n\n参照: [`../functional-ts-ja/SKILL.md` §1「`Readonly<>` で不変性を保証する」](../functional-ts-ja/SKILL.md)\n\n兆候: ドメインオブジェクトの型定義が `Readonly<…>`（または各プロパティの `readonly`）で保護されていない。状態変更は新しいオブジェクトの生成で表現する。\n\n#### 1.9 「1 概念 1 ファイル」の構成になっているか\n\n参照: [`../functional-ts-ja/SKILL.md` §1「ファイル構成: 1概念1ファイル」](../functional-ts-ja/SKILL.md)\n\n兆候: `types.ts`, `models.ts`, `domain.ts` のような catch-all ファイルに多数のドメイン型が集約されている、特に companion object が別ファイルにある場合。barrel file（`index.ts`）は re-export のみ。\n\n### 2. 関数による状態遷移\n\n参照: [`../functional-ts-ja/SKILL.md` §2](../functional-ts-ja/SKILL.md) および [`../functional-ts-ja/state-modeling.md`](../functional-ts-ja/state-modeling.md)\n\n#### 2.1 状態遷移関数が引数型で遷移元を制約しているか\n\n兆候: 遷移関数の引数型が個別の状態（`Waiting`）ではなく union（`TaxiRequest`）になっている。広い型を受け取ると、無効な遷移元での呼び出しが許されてしまう。\n\n#### 2.2 Discriminated Union の `switch` に `assertNever` があるか\n\n参照: [`../functional-ts-ja/SKILL.md` §2「網羅性チェック」](../functional-ts-ja/SKILL.md)\n\n兆候: `kind` で分岐する `switch` に `default: return assertNever(x)` がない。新バリアント追加時にコンパイルエラーで検出できなくなる。\n\n### 3. エラーハンドリング — Railway Oriented Programming\n\n参照: [`../functional-ts-ja/SKILL.md` §3](../functional-ts-ja/SKILL.md), [`../functional-ts-ja/error-handling.md`](../functional-ts-ja/error-handling.md), プロジェクトの Result ライブラリガイド ([`../functional-ts-ja/result-libraries/`](../functional-ts-ja/result-libraries/))。\n\n#### 3.1 ドメイン層で例外を throw していないか\n\n兆候: エンティティ・値オブジェクト・ユースケース内の `throw`。`Result` 型への変更を提案する。許容: `assertNever` 内の throw（到達不能）、インフラ層の予期しない障害。\n\n#### 3.2 エラー型が Discriminated Union になっているか\n\n兆候: `Error` のサブクラス、自由形式の `string` エラーコード、`Result<T, string>`。Discriminated Union（`{ kind: \"DriverNotAvailable\"; driverId } | { kind: \"RequestAlreadyAssigned\" }`）への変更を提案し、呼び出し元が網羅的に分岐できるようにする。\n\n#### 3.3 Result チェーンを使って合成しているか（即 unwrap していないか）\n\nプロジェクトに対応する Result ライブラリの API（`.map`, `.andThen`, `Result.do` など）でチェーン合成しているかを確認する。即 unwrap して if/else に展開している場合は、`../functional-ts-ja/result-libraries/` 配下の該当ガイドを引用して適切なコンビネータを提案する。\n\n### 4. 境界の防御\n\n参照: [`../functional-ts-ja/SKILL.md` §4](../functional-ts-ja/SKILL.md), [`../functional-ts-ja/boundary-defense.md`](../functional-ts-ja/boundary-defense.md), プロジェクトのバリデーションライブラリガイド ([`../functional-ts-ja/validation-libraries/`](../functional-ts-ja/validation-libraries/))。\n\n#### 4.1 すべての外部境界にスキーマバリデーションがあるか\n\n兆候: API ハンドラ、DB 結果のマッピング、キュー・メッセージハンドラ、ファイル・設定の読み込み、環境変数の読み取りなどで、生のデータをバリデーションライブラリ（Zod / Valibot / ArkType）でパースせずにドメイン型として扱っている。\n\n#### 4.2 `as` による型アサーションがないか\n\n参照: [`../functional-ts-ja/SKILL.md` §4「型アサーション（`as`）を使わない」](../functional-ts-ja/SKILL.md)\n\nすべての `as` を洗い出し、以下のいずれかに該当するか確認する:\n- 外部データ: スキーマパースで置き換えるべき。\n- Branded Type の生成関数内の `as`: バリデーションライブラリを使わない場合（`unique symbol` パターン）のみ許容。\n- 内部データ: 型推論で解決可能なはず。解決できないなら型設計が誤っている可能性が高い。\n\n#### 4.3 PII フィールドが `Sensitive<T>` でラップされているか\n\n参照: [`../functional-ts-ja/SKILL.md` §4「PIIの防御」](../functional-ts-ja/SKILL.md), [`../functional-ts-ja/boundary-defense.md`](../functional-ts-ja/boundary-defense.md)\n\n兆候: 個人情報を含みうるフィールド（氏名、メールアドレス、電話番号、住所、各種ID、決済情報、健康・診断情報、IP アドレスなど）が素の `string` / `number` のまま。特にログやエラーメッセージに出力されうるオブジェクトを重点的にチェックする。バリデーションスキーマで `Sensitive.of` による自動ラップが行われているかも確認する。\n\n### 5. 宣言的なスタイル\n\n参照: [`../functional-ts-ja/SKILL.md` §5](../functional-ts-ja/SKILL.md), [`../functional-ts-ja/state-modeling.md`](../functional-ts-ja/state-modeling.md)\n\n#### 5.1 配列操作が宣言的か\n\n兆候: `filter` / `map` / `reduce` で表現できる変換を、`for` / `for…of` ループで命令的に組み立てている。述語関数を companion object に定義し、`tasks.filter(Task.isActive)` のように書くよう提案する。\n\n#### 5.2 ドメインイベントが不変レコードとして発行されているか\n\n兆候: 状態変更コードが共有のイベントログを mutate している、あるいは state-modeling ガイドが要求する場面でドメインイベントが発行されていない。`Readonly<{ eventId; eventAt; eventName; payload; aggregateId }>` としてリポジトリと分離して記録する。\n\n### 6. テストデータ\n\n参照: [`../functional-ts-ja/SKILL.md` §6](../functional-ts-ja/SKILL.md)\n\n#### 6.1 フィクスチャが `as const satisfies Type` で定義されているか\n\n兆候: テストフィクスチャが `: Type =` や `as Type` で型付けされており、discriminant のリテラル型が `string` に widening されている。`as const satisfies Type` への変更を提案し、`kind` のリテラル型を保持する。\n\n## 指摘の書き方\n\n各指摘には以下を含める:\n\n1. **何が問題か**: 具体的なコードの場所（`path:line`）。\n2. **なぜ問題か**: 原則（`../functional-ts-ja/...` への参照リンク付き）と、違反した場合のリスク。\n3. **どう直すか**: 修正案のコード例。\n\n```\n### メソッド記法の使用\n\n`src/repository/task-repository.ts:15`\n\n`save(task: Task): Promise<void>` はメソッド記法です。\n[`../functional-ts-ja/SKILL.md` §1「関数プロパティ記法を使う」](../functional-ts-ja/SKILL.md)\nにあるとおり、メソッド記法ではパラメータが bivariant になり、\n`save(task: DoingTask): Promise<void>` のような狭い型の実装が依存注入時に型チェックを通過します。\n\n修正案:\n\\`\\`\\`typescript\ntype TaskRepository = {\n  save: (task: Task) => Promise<void>;\n};\n\\`\\`\\`\n```\n\n## 重要度\n\n| 重要度 | 項目 | 理由 |\n|--------|------|------|\n| High | `as` 型アサーション (4.2) | ランタイムエラーの直接原因 |\n| High | PII 未保護 (4.3) | コンプライアンス違反リスク |\n| High | 外部境界のスキーマバリデーション不足 (4.1) | ランタイムエラーの直接原因 |\n| High | 意味の異なるプリミティブの Branded Types 不足 (1.7) | 異種 ID の取り違えがランタイムで発生 |\n| Medium | class 使用 (1.3) | 拡張時の型安全性低下 |\n| Medium | optional プロパティでの状態モデリング (1.1) | 不正な状態が表現可能になる |\n| Medium | ドメイン層での `throw` (3.1) | エラーハンドリングの一貫性欠如 |\n| Medium | 非 Discriminated Union のエラー型 (3.2) | 呼び出し元が網羅的に分岐できない |\n| Medium | `assertNever` 不足 (2.2) | 新バリアント追加時の見落とし |\n| Medium | union 型を受ける状態遷移関数 (2.1) | 無効な遷移がコンパイルを通る |\n| Medium | catch-all 型ファイル (1.9) | 循環依存・型と振る舞いの分離 |\n| Medium | Companion Object パターン違反・スキーマ単独 export (1.4) | 実装詳細の漏洩 |\n| Low | メソッド記法 (1.6) | 特定条件下でのみ問題顕在化 |\n| Low | ドメイン型の `interface` 使用 (1.5) | declaration merging 事故は稀 |\n| Low | `Readonly<>` 未使用のドメイン型 (1.8) | mutation はレビューで気付ける場合が多い |\n| Low | discriminant が `kind` 以外 (1.2) | バグというよりスタイル不一致 |\n| Low | 命令的な配列ループ (5.1) | 正確性ではなく可読性 |\n| Low | ドメインイベント不発行 (5.2) | event sourcing の採否次第 |\n| Low | フィクスチャに `as const satisfies` がない (6.1) | 実務上はテストで検出される |","tags":["functional","review","principles","iwasa-kosui","agent-skills"],"capabilities":["skill","source-iwasa-kosui","skill-functional-ts-review-ja","topic-agent-skills"],"categories":["functional-ts-principles"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/iwasa-kosui/functional-ts-principles/functional-ts-review-ja","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add iwasa-kosui/functional-ts-principles","source_repo":"https://github.com/iwasa-kosui/functional-ts-principles","install_from":"skills.sh"}},"qualityScore":"0.458","qualityRationale":"deterministic score 0.46 from registry signals: · indexed on github topic:agent-skills · 17 github stars · SKILL.md body (9,002 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-10T07:03:39.718Z","embedding":null,"createdAt":"2026-05-10T07:03:39.718Z","updatedAt":"2026-05-10T07:03:39.718Z","lastSeenAt":"2026-05-10T07:03:39.718Z","tsv":"'/functional-ts-ja':651 '/functional-ts-ja/boundary-defense.md':59,60,482,483,542,543 '/functional-ts-ja/error-handling.md':57,58,407,408 '/functional-ts-ja/result-libraries':77,78,412,413,474 '/functional-ts-ja/skill.md':54,55,105,106,117,121,145,150,169,173,195,200,227,233,247,251,277,281,309,313,328,332,357,359,383,386,404,406,479,481,508,513,538,541,567,569,611,613,666,669 '/functional-ts-ja/state-modeling.md':61,62,361,362,570,571 '/functional-ts-ja/validation-libraries':66,67,283,284,485,486 '/skill.md':93 '1':50,109,118,146,170,196,228,248,278,310,322,324,329,643,667 '1.1':111,722 '1.2':139,785 '1.3':164,717 '1.4':190,760 '1.5':222,770 '1.6':244,764 '1.7':271,710 '1.8':304,777 '1.9':321,751 '15':660 '1概念1ファイル':331 '2':84,354,358,384,648 '2.1':363,744 '2.2':374,739 '3':86,398,405,655 '3.1':414,727 '3.2':431,734 '3.3':454 '4':96,476,480,509,539 '4.1':487,703 '4.2':504,694 '4.3':532,699 '5':101,564,568 '5.1':572,789 '5.2':590,793 '6':608,612 '6.1':614,803 'aggregateid':606 'andthen':465 'api':463,490 'arktyp':502 'arktype.md':71 'assertnev':380,394,426,737 'augment':242 'barrel':346 'bivari':258,672 'brand':16,206,273,279,520,707 'byethrow.md':81 'catch':339,748 'catch-al':338,747 'class':166,180,188,715 'code':33 'companion':14,175,184,191,197,212,217,343,584,755 'const':204,617,635,800 'date':134 'db':492 'declar':234,771 'default':392 'discrimin':12,113,119,140,159,171,182,375,433,445,628,731,781 'discriminantは':147 'doingtask':263,676 'domain.ts':336 'driverid':131,449 'drivernotavail':448 'email':291 'error':437 'event':794 'eventat':603 'eventid':602 'eventnam':604 'export':352,759 'file':347 'filter':575 'fp-ts.md':82 'function':2,8,31,36,42,90 'functional-ts-ja':7,35,41,89 'functional-ts-review-ja':1 'high':691,696,701,705 'id':287,712 'if/else':472 'index.ts':348 'interfac':224,231,240,768 'ip':554 'ja':5,10,38,44,92 'kind':142,148,157,162,388,447,450,639,783 'line':647 'low':762,766,774,780,787,791,797 'map':464,576 'medium':714,719,724,729,736,741,746,754 'merg':235,772 'model':599 'models.ts':335 'mutat':594,778 'neverthrow.md':80 'number':295,558 'object':15,176,185,192,198,213,218,344,585,756 'option':124,720 'option-t.md':83 'orderid':290 'orient':401 'package.json':64,73 'path':646 'payload':605 'pii':27,533,697 'piiの防御':540 'program':402 'promis':256,269,664,677,686 'railway':400 're':351 're-export':350 'readon':306,311,316,318,601,775 'reduc':577 'requestalreadyassign':451 'result':75,410,423,442,455,461 'result.do':466 'result型によるエラーハンドリング':22 'return':393 'review':4,34 'satisfi':618,636,801 'save':253,261,266,661,674,683 'schema':215 'sensit':535 'sensitive.of':562 'skill' 'skill-functional-ts-review-ja' 'sourc':795 'source-iwasa-kosui' 'src/repository/task-repository.ts':659 'starttim':133 'state':129,154,598 'state-model':597 'status':153 'string':126,130,132,294,440,444,557,630 'switch':378,390 'symbol':302,526 'tag':155 'task':254,255,262,267,268,662,663,675,684,685 'task.isactive':588 'taskrepositori':682 'tasks.filter':587 'taxirequest':370 'throw':416,422,428,726 'topic-agent-skills' 'ts':3,9,37,43,91 'type':17,152,207,229,238,274,521,619,623,626,637,681,708 'types.ts':334 'typescript':32,680 'typesで意味を区別する':280 'union':13,114,136,183,369,376,434,446,732,742 'unionで状態を表現する':120,172 'uniqu':301,525 'unwrap':458,470 'userid':289 'valibot':501 'valibot.md':70 'wait':367 'widen':632 'x':395 'xxxassigndriv':220 'xxxschema':210 'zod':500 'zod.md':69 'あるいは':596 'および':174,360 'か':307 'が':141,782 'があるか':381 'がない':396,802 'が別ファイルにある場合':345 'が型チェックを通過する':264 'が素の':293,556 'が適用されているか':275 'されている':633 'して':471 'していないか':417,459 'している':595 'すべての':514 'すべての外部境界にスキーマバリデーションがあるか':488 'ではなく':211,232,368 'でスキャンする':95 'でチェーン合成しているかを確認する':468 'でパースせずにドメイン型として扱っている':503 'でモデリングしているか':115 'でラップされているか':536 'で不変性を保証する':312 'で保護されていない':319 'で分岐する':389 'で型付けされており':627 'で定義されているか':620 'で定義する':239 'で扱われている':296 'で統一されているか':143 'で統一する':149 'で表現できる変換を':578 'と':45,653 'としてリポジトリと分離して記録する':607 'どう直すか':656 'ない場合は':300 'なぜ問題か':649 'など':156,467 'に':379,391,631 'にあるとおり':670 'にし':137 'になっている':371 'になっているか':435 'になり':259,673 'により型の形状が暗黙に変わる危険がある':236 'による型アサーションがないか':506 'による自動ラップが行われているかも確認する':563 'に定義し':586 'に展開している場合は':473 'に応じた':74 'に応じたバリデーションライブラリガイド':65 'に置くべきドメインロジックが':219 'に集約されているか':205 'の':214,377 'のまま':559 'のみ':353 'のみ許容':528 'のような':337 'のような独立関数として散在していないか':221 'のような狭い型の実装が依存注入時に型チェックを通過します':678 'のように書くよう提案する':589 'のエラー型':733 'のサブクラス':438 'のバリデーションスキーマが':208 'のリテラル型が':629 'のリテラル型を保持する':640 'の取り違えがランタイムで発生':713 'の場合のみ許容':243 'の採否次第':796 'の構成になっているか':326 'の構造をそのまま反映する':107 'の状態フィールドを持つ単一の型':127 'の生成関数内の':522 'の章立てと一致':94 'は':349 'はパラメータが':257 'はメソッド記法です':665 'はライブラリの型拡張':241 'はレビューで気付ける場合が多い':779 'への参照リンク付き':652 'への変更を提案し':452,638 'への変更を提案する':163,270 'または各プロパティの':317 'も参照':285 'や':624 'や意味の異なる値':288 'を使う':230 'を使っていないか':167,225 'を使っている場合':181 'を使わない':512 'を洗い出し':516 'アドレスなど':555 'インフラ層の予期しない障害':430 'エラーコード':441 'エラーハンドリング':399 'エラーハンドリングの一貫性欠如':728 'エラー型が':432 'エンティティ':419 'ガイドが要求する場面でドメインイベントが発行されていない':600 'キャスト不要':299 'キュー':494 'コンプライアンス違反リスク':700 'コードベースの一貫性のため':161 'コード閲覧の前に以下を読み':52 'サーバーサイドtypescriptコードを関数型ドメインモデリング原則に照らしてレビューする':6 'スキルが定める関数型ドメインモデリング原則に照らしてサーバーサイドtypescriptコードをレビューする':39 'スキルと同じナレッジを参照し':11 'スキーマバリデーション':24 'スキーマパースで置き換えるべき':519 'スキーマ単独':758 'スタンドアロンの':209 'チェック項目':103 'チェック項目は':104 'チェーンを使って合成しているか':456 'テストデータ':609 'テストフィクスチャが':622 'ドメインイベントが不変レコードとして発行されているか':591 'ドメインイベント不発行':792 'ドメインエンティティ':178 'ドメインオブジェクトが':305 'ドメインオブジェクトの型定義が':315 'ドメインモデルに':165 'ドメイン型に':223 'ドメイン型の':767 'ドメイン型は':237 'ドメイン層での':725 'ドメイン層で例外を':415 'ドメイン状態を':112 'ハンドラ':491 'バグというよりスタイル不一致':786 'バリデーションスキーマで':561 'バリデーションライブラリがある場合はそのブランド機能で':297 'バリデーションライブラリを使わない場合':524 'パターン':177,199,527 'パターンで定義されているかを確認する':303 'パターンに従っているか':193 'パターンへの変更を提案する':186 'パターン違反':757 'ファイル':325,496 'ファイルに多数のドメイン型が集約されている':341 'ファイル構成':19,330 'フィクスチャが':615 'フィクスチャに':798 'フィールドが':534 'プロジェクトに対応する':460 'プロジェクトの':63,72,409 'プロジェクトのバリデーションライブラリガイド':282,484 'プロパティでの状態モデリング':721 'プロパティと':125 'プロパティとして公開されているか':216 'メソッド記法':252,763 'メソッド記法ではなく':250 'メソッド記法ではパラメータが':671 'メソッド記法の使用':658 'メッセージハンドラ':495 'メールアドレス':547 'ユースケース内の':421 'ライブラリの':462 'ライブラリガイド':76,411 'ランタイムエラーの直接原因':695,704 'ループで命令的に組み立てている':582 'レビュー対象のファイルを読む':85 'レビュー手順':49 '不変性':18 '不正な状態が表現可能になる':723 '不足':709,738 '事故は稀':773 '以下のいずれかに該当するか確認する':517 '以下のチェック項目を':87 '以下を確認する':201 '以外':784 '以外の':158 '住所':549 '何が問題か':644 '使用':716,769 '例':128 '依存注入時に狭い型の実装':260 '保護':28 '修正案':679 '修正案のコード例':657 '修正案を添えて指摘する':100 '個人情報を含みうるフィールド':545 '値オブジェクト':420 '値オブジェクトの定義に':179 '健康':552 '兆候':122,151,286,314,333,365,387,418,436,489,544,574,592,621 '具体的なコードの場所':645 '内の':427 '内部データ':529 '到達不能':429 '即':457,469 '原則':98,650 '原則のインデックス':56 '原則の順序':88 '原則ナレッジを先に読み込む':51 '参照':116,144,168,194,226,246,276,308,327,356,382,403,478,507,537,566,610 '各チェック項目はあちらの章と1対1で対応し':47 '各指摘には以下を含める':642 '各種id':550 '各項目は正典の章へリンクする':108 '同じナレッジを参照する':46 '名':160 '呼び出し元が網羅的に分岐できない':735 '呼び出し元が網羅的に分岐できるようにする':453 '命令的な配列ループ':788 '型と同名の':203 '型と振る舞いの分離':753 '型によるドメインモデリング':110 '型に関連する操作が':202 '型への変更を提案する':424 '型を受ける状態遷移関数':743 '型アサーション':510,693 '型ファイル':750 '型安全なテストデータをチェックする':30 '型定義内でメソッド記法を使っていないか':245 '型推論で解決可能なはず':530 '境界の防御':23,477 '外部データ':518 '外部ライブラリが':187 '外部境界のスキーマバリデーション不足':702 '多数の':123 '実務上はテストで検出される':804 '実装詳細の漏洩':761 '宣言的なスタイル':565 '宣言的スタイル':29 '広い型を受け取ると':372 '循環依存':752 '意味の異なるプリミティブに':272 '意味の異なるプリミティブの':706 '拡張時の型安全性低下':718 '指摘で正典の原則を引けるようにする':53 '指摘の書き方':641 '新バリアント追加時にコンパイルエラーで検出できなくなる':397 '新バリアント追加時の見落とし':740 '未使用のドメイン型':776 '未保護':698 '本スキルは':40 '根拠の所在を相対リンクで明示する':48 '概念':323 '正確性ではなく可読性':790 '氏名':546 '決済情報':551 '無効な遷移がコンパイルを通る':745 '無効な遷移元での呼び出しが許されてしまう':373 '特に':342 '特にログやエラーメッセージに出力されうるオブジェクトを重点的にチェックする':560 '特定条件下でのみ問題顕在化':765 '状態ごとに型を分けて':135 '状態固有プロパティを必須にするよう提案する':138 '状態変更は新しいオブジェクトの生成で表現する':320 '状態変更コードが共有のイベントログを':593 '状態遷移関数が引数型で遷移元を制約しているか':364 '理由':99,690 '環境変数の読み取りなどで':498 '生のデータをバリデーションライブラリ':499 '異種':711 '禁止':26 '純粋関数による状態遷移':20 '結果のマッピング':493 '継承を要求する場合は正当な逸脱':189 '網羅性チェック':21,385 '自由形式の':439 '解決できないなら型設計が誤っている可能性が高い':531 '設定の読み込み':497 '許容':425 '診断情報':553 '述語関数を':583 '違反した場合のリスク':654 '違反ではないが改善余地がある場合は提案として伝える':102 '違反を発見した場合':97 '遷移関数の引数型が個別の状態':366 '配下の':68,79 '配下の該当ガイドを引用して適切なコンビネータを提案する':475 '配列操作が宣言的か':573 '重要度':687,688 '金額など':292 '関数による状態遷移':355 '関数プロパティ記法':265 '関数プロパティ記法を使う':249,668 '電話番号':548 '非':730 '項目':689","prices":[{"id":"61d2f232-555e-4223-93d5-1800eac5d594","listingId":"1ebbd035-79a3-4476-981e-e79b6898985f","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"iwasa-kosui","category":"functional-ts-principles","install_from":"skills.sh"},"createdAt":"2026-05-10T07:03:39.718Z"}],"sources":[{"listingId":"1ebbd035-79a3-4476-981e-e79b6898985f","source":"github","sourceId":"iwasa-kosui/functional-ts-principles/functional-ts-review-ja","sourceUrl":"https://github.com/iwasa-kosui/functional-ts-principles/tree/main/skills/functional-ts-review-ja","isPrimary":false,"firstSeenAt":"2026-05-10T07:03:39.718Z","lastSeenAt":"2026-05-10T07:03:39.718Z"}],"details":{"listingId":"1ebbd035-79a3-4476-981e-e79b6898985f","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"iwasa-kosui","slug":"functional-ts-review-ja","github":{"repo":"iwasa-kosui/functional-ts-principles","stars":17,"topics":["agent-skills"],"license":"mit","html_url":"https://github.com/iwasa-kosui/functional-ts-principles","pushed_at":"2026-05-10T07:01:36Z","description":null,"skill_md_sha":"209367d3c3fb27a504b5116cae35006750f48667","skill_md_path":"skills/functional-ts-review-ja/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/iwasa-kosui/functional-ts-principles/tree/main/skills/functional-ts-review-ja"},"layout":"multi","source":"github","category":"functional-ts-principles","frontmatter":{"name":"functional-ts-review-ja","license":"MIT","description":"サーバーサイドTypeScriptコードを関数型ドメインモデリング原則に照らしてレビューする。`functional-ts-ja` スキルと同じナレッジを参照し、Discriminated Union、Companion Object、Branded Types、不変性、ファイル構成、純粋関数による状態遷移、網羅性チェック、Result型によるエラーハンドリング、境界の防御（スキーマバリデーション・`as` 禁止・PII 保護）、宣言的スタイル、型安全なテストデータをチェックする。"},"skills_sh_url":"https://skills.sh/iwasa-kosui/functional-ts-principles/functional-ts-review-ja"},"updatedAt":"2026-05-10T07:03:39.718Z"}}