バクラク請求書発行では、請求書・見積書・納品書などのPDFレイアウトをGUIで自由にデザインできるビジュアルエディタを提供しています。テキスト・画像・動的テーブルなど6種類のノードを自由に配置し、実際の書類データをバインドしてPDFを生成する仕組みです。
しかし自由度が高いほど、コードの複雑さも増します。テキストノードにはフォント設定があり、テーブルノードには列定義があり、画像ノードにはフィット方法がある——同じ「ノード」でも中身はまったく別物です。さらにノードの値は固定テキストかもしれないし、書類データから動的に取得するかもしれない。こうした組み合わせの中で「テキストノードなのにテーブルの列定義を参照してしまう」ような取り違えをどう防ぐか。人のレビューに頼るのではなく、型に任せられないか—— 本トークはその問いから始まります。
Protocol Buffersのoneof定義からZod経由でDiscriminated Unionを自動生成する仕組み、Conditional Typeでノード型名から値型を安全に取り出すパターン、DeepPartialでReducerの部分更新を型安全にする設計、そして同一の型定義でエディタのプレビューとPDF本番生成の両方を駆動するアーキテクチャを、具体的なコードとともに紹介します。