判別フィールドだけ見る型ガードは値の実在を保証しない — 空レコードを undefined 値で実体化する層と組むと実行時に落ちる
TypeScript
テスト
知識
運用
TypeScript のユーザー定義型ガード(x is T の述語)が dataType のような判別フィールドのみを検査して T へ絞り込む実装は、payload(value)の形を実行時に検証していない。絞り込み後の型で value が non-nullable に見えても、それは表明であって保証ではない。
破綻パターン
ORM・リポジトリ層が「未設定の項目」を、判別フィールド付き・value が undefined の空オブジェクトとして実体化しエンティティへマージする設計と組み合わさると、型ガードを通過した直後の value への配列アクセス(map 相当)が TypeError になる。さらに行単位のエラー握りつぶし(continue-on-error の catch)と組むと、クラッシュではなく「正常データが失敗として誤集計される」といういっそう気づきにくい症状に変わる。型チェックと lint は全て通る。
判断基準
- 型ガード経由で value にアクセスするコードを書く・レビューするときは、値の生成元を遡り「空・未設定がどう実体化されるか」を確認する。空が undefined で来る系では、ガード通過後も Array.isArray 等の実在チェックで防御するか、型ガード自体を値の形まで検査する述語に直す。
- 判別フィールドの種類ごとに空の表現が違うことがある(例: boolean 項目だけは空を false で実体化し、他は undefined、など)。1種類の確認で全種類を安全と判断しない。
検証
未設定項目を持つレコードを、手組みではなく実体化経路(リポジトリの read やそのヘルパ)経由で生成してテストに含める。手組みのテストデータは「値のある項目」だけで構成しがちで、この穴を素通しする。