Form events errors
martenb opened this issue · 3 comments
Hi, i have problems with latest nette/forms and phpstan 1.0.. i will describe it on presenter, but same errors are in control...
<?php declare(strict_types = 1);
namespace App\Presenters;
use Nette\Application\UI\Form;
use Nette\Application\UI\Presenter;
use Nette\Utils\ArrayHash;
final class HomepagePresenter extends Presenter
{
protected function createCompomentForm(): Form
{
$form = new Form();
$form->onSuccess[] = function (Form $form, ArrayHash $values): void {
};
$form->onSuccess[] = [$this, 'formOnSuccess'];
return $form;
}
public function formOnSuccess(Form $form, ArrayHash $values): void
{
}
} ------ ---------------------------------------------------------------------------------
Line Presenters/HomepagePresenter.php
------ ---------------------------------------------------------------------------------
15 Array (array<callable(Nette\Application\UI\Form, mixed): void>) does not accept
Closure(Nette\Application\UI\Form, Nette\Utils\ArrayHash): void.
18 Array (array<callable(Nette\Application\UI\Form, mixed): void>) does not accept
array{$this(App\Presenters\HomepagePresenter), 'formOnSuccess'}.
------ ---------------------------------------------------------------------------------
Given the types from the stub:
phpstan-nette/stubs/Forms/Form.stub
Lines 8 to 9 in f4654b2
/** @var array<callable(static, mixed): void> */
public $onSuccess;this is expected behaviour by PHPStan. Because you're narrowing down the type of the second parameter from mixed to ArrayHash.
I understand that Nette contains some magic (https://github.com/nette/forms/blob/0f0c770db65ce2a18fc766b8b718b53e081ac8e2/src/Forms/Form.php#L424-L442) that will prevent this bug from happening. But PHPStan currently doesn't have the facilities to describe this behaviour, so feel free to just ignore the error: https://phpstan.org/user-guide/ignoring-errors
I just noticed this with Container::onValidate – the property is expected to contain array<callable(static, T): void|callable(static, array): void|callable(T): void|callable(array): void> where T can be any object type but that is not expressible in PHPStan type language since containers like arrays are invariant in their item template types.
Would changing the stubs to just array<callable> and adding specific rules as a replacement be acceptable?
Comparison of the various type signatures: https://phpstan.org/r/a8969a90-ac6f-47f6-b11f-8df10e8f7e95