From 20203d3076fb52c134d9bfa5b9d6952f9a369a9b Mon Sep 17 00:00:00 2001 From: Takuma Kajikawa Date: Wed, 10 Jun 2026 21:35:03 +0900 Subject: [PATCH] docs: document instanceof narrowing limitation, recommend isOk()/isErr() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit instanceof による絞り込みは PHPStan の制限で型引数が失われ、 unwrap() が mixed になる(tests/Types/result.php の testInstanceofOkNarrowing / testMatchArmNarrowing でピン留め済み)。 README と Result の PHPDoc に注記し、値を取り出す分岐では isOk()/isErr() を使うよう誘導する。 --- README.md | 5 ++++- src/Result.php | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ef462f5..baf398b 100644 --- a/README.md +++ b/README.md @@ -146,7 +146,10 @@ and leans on several of its generics features: - **Sealed interface** — `Result` is annotated with `@phpstan-sealed Ok|Err`, so PHPStan knows `Ok` and `Err` are the only implementations. A `match (true)` over `instanceof` checks is recognized as exhaustive, and the `else` branch of an - `instanceof Ok` check narrows to `Err`. + `instanceof Ok` check narrows to `Err`. Note that `instanceof` narrowing loses + the type arguments (a known PHPStan limitation: `Result` narrows to + plain `Ok`, so `unwrap()` becomes `mixed`) — use `instanceof` for exhaustiveness + checks only, and narrow with `isOk()`/`isErr()` when you need the values. - **Covariant type parameters** — `T` and `E` are declared `@template-covariant`, so `Ok` (which is `Result`) and `Err` (which is `Result`) are assignable to any `Result`. A function declared to return diff --git a/src/Result.php b/src/Result.php index e358e3e..67f2fd4 100644 --- a/src/Result.php +++ b/src/Result.php @@ -7,6 +7,10 @@ /** * Result型は、成功(Ok)または失敗(Err)を表現します。 * + * 注意: instanceof による絞り込みでは型引数が失われます(PHPStan の既知の制限。 + * Result が型引数なしの Ok になり unwrap() は mixed になる)。 + * 値を取り出す分岐では isOk() / isErr() で絞り込んでください。 + * * @template-covariant T 成功時の値の型 * @template-covariant E 失敗時のエラーの型 *