Skip to content

[Refactor] Tighten OpenApiValidationResult::failure() / errors() to non-empty-array<string> via PHPStan #97

@wadakatu

Description

@wadakatu

背景

#73OpenApiValidationResult::failure([]) を runtime に拒否する実装を入れた (#96)。これにより不正な構築は throw されるが、型シグネチャ上は依然 string[] のままで静的検出が効かない。

  • failure(array $errors, ?string $matchedPath = null) のパラメータは @param string[] $errors のため、failure($maybeEmpty) は PHPStan に検出されず実行時まで到達する
  • errors(): array の戻り値も string[] のため、Failure に対して呼んでも PHPStan は「空配列の可能性」を保持し、errorMessage() の consumer は静的に non-emptiness を主張できない

#73 自体はこの型注釈強化を「PHPStan extended types の導入は別議論」として明示的に scope 外にしていたため、フォローアップとして切る。

提案

PHPStan extended types で non-empty-array<string> を導入する:

  1. failure() のパラメータ:

    /** @param non-empty-array<string> $errors */
    public static function failure(array $errors, ?string $matchedPath = null): self
  2. errors() の戻り値: 現状 Failure 以外でも呼べるため、無条件 non-empty-array<string> は嘘になる。選択肢:

    • (A) 据え置きstring[] のまま。errors() は3 outcome 共通アクセサなので妥当
    • (B) conditional return type — 呼び出し前に outcome で narrow する形に変更 (大きめの変更)
    • (C) 専用アクセサ追加failureErrors(): non-empty-array<string> を新設し、Failure 以外で呼ぶと throw

    推奨は (A) + パラメータのみ強化。consumer 側で必要なら assert($result->isValid() === false) 後に errors() を narrow する。

  3. PHPStan の baseline / ignore に既存エラーが出る場合は同 PR で修正する (workspace ルール: PHPStan エラーは ignore せず根本修正)

受け入れ条件

  • failure() のパラメータが non-empty-array<string> で注釈されている
  • vendor/bin/phpstan analyse が pass する (新規 ignore なし)
  • 空配列リテラル failure([]) が PHPStan エラーとして検出される (テスト用に一時的に書いてみて確認)
  • 既存の failure(['...']) 呼び出し7箇所が PHPStan に通る

スコープ外

  • errors() の conditional return type / 専用アクセサ案 ((B), (C)) — 別 issue で議論
  • Success / Skipped ファクトリの引数強化 — そもそも引数を取らないので対象外

Refs

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions