-
Notifications
You must be signed in to change notification settings - Fork 486
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Do not generalize class-level
@template
type in method call
- Loading branch information
1 parent
4d5bf20
commit 11268e5
Showing
3 changed files
with
108 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
<?php | ||
|
||
namespace Bug10473; | ||
|
||
use ArrayAccess; | ||
use function PHPStan\Testing\assertType; | ||
|
||
/** | ||
* @template TRow of array<string, mixed> | ||
*/ | ||
class Rows | ||
{ | ||
|
||
/** | ||
* @param list<TRow> $rowsData | ||
*/ | ||
public function __construct(private array $rowsData) | ||
{} | ||
|
||
/** | ||
* @return Row<TRow>|NULL | ||
*/ | ||
public function getByIndex(int $index): ?Row | ||
{ | ||
return isset($this->rowsData[$index]) | ||
? new Row($this->rowsData[$index]) | ||
: NULL; | ||
} | ||
} | ||
|
||
/** | ||
* @template TRow of array<string, mixed> | ||
* @implements ArrayAccess<key-of<TRow>, value-of<TRow>> | ||
*/ | ||
class Row implements ArrayAccess | ||
{ | ||
|
||
/** | ||
* @param TRow $data | ||
*/ | ||
public function __construct(private array $data) | ||
{} | ||
|
||
/** | ||
* @param key-of<TRow> $key | ||
*/ | ||
public function offsetExists($key): bool | ||
{ | ||
return isset($this->data[$key]); | ||
} | ||
|
||
/** | ||
* @template TKey of key-of<TRow> | ||
* @param TKey $key | ||
* @return TRow[TKey] | ||
*/ | ||
public function offsetGet($key): mixed | ||
{ | ||
return $this->data[$key]; | ||
} | ||
|
||
public function offsetSet($key, mixed $value): void | ||
{ | ||
$this->data[$key] = $value; | ||
} | ||
|
||
public function offsetUnset($key): void | ||
{ | ||
unset($this->data[$key]); | ||
} | ||
|
||
/** | ||
* @return TRow | ||
*/ | ||
public function toArray(): array | ||
{ | ||
return $this->data; | ||
} | ||
|
||
} | ||
|
||
class Foo | ||
{ | ||
|
||
/** @param Rows<array{foo: int<0, max>}> $rows */ | ||
public function doFoo(Rows $rows): void | ||
{ | ||
assertType('Bug10473\Rows<array{foo: int<0, max>}>', $rows); | ||
|
||
$row = $rows->getByIndex(0); | ||
|
||
if ($row !== NULL) { | ||
assertType('Bug10473\Row<array{foo: int<0, max>}>', $row); | ||
$fooFromRow = $row['foo']; | ||
|
||
assertType('int<0, max>', $fooFromRow); | ||
assertType('array{foo: int<0, max>}', $row->toArray()); | ||
} | ||
|
||
} | ||
|
||
} |