php-http / client-common

Common HTTP Client implementations and tools for HTTPlug
http://httplug.io
MIT License
1.01k stars 53 forks source link

More specific plugin type doc #199

Closed GrahamCampbell closed 4 years ago

GrahamCampbell commented 4 years ago
Q A
Bug fix? yes
New feature? yes
BC breaks? no
Deprecations? no yes
License MIT

Static analysers (such as Psalm) complain if someone adds this typing information to their own class which extends this interface because what they have affectively done is specialised the types, which is not allowed. It's the same as an interface saying string|int but the implementation only accepting string. So, with this in mind, we should take the opportunity to provide the most specific type information we can.

For reference, an error produced by Psalm (without this PR):

ERROR: MoreSpecificImplementedParamType - src/HttpClient/Plugin/Authentication.php:62:71 - Argument 2 of Bitbucket\HttpClient\Plugin\Authentication::handleRequest has the more specific type 'callable(Psr\Http\Message\RequestInterface):Http\Promise\Promise', expecting 'callable' as defined by Http\Client\Common\Plugin::handleRequest (see https://psalm.dev/140)
    public function handleRequest(RequestInterface $request, callable $next, callable $first): Promise

ERROR: MoreSpecificImplementedParamType - src/HttpClient/Plugin/Authentication.php:62:87 - Argument 3 of Bitbucket\HttpClient\Plugin\Authentication::handleRequest has the more specific type 'callable(Psr\Http\Message\RequestInterface):Http\Promise\Promise', expecting 'callable' as defined by Http\Client\Common\Plugin::handleRequest (see https://psalm.dev/140)
    public function handleRequest(RequestInterface $request, callable $next, callable $first): Promise

and by PHPStan:

 ------ ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
  Line   HttpClient/Plugin/Authentication.php                                                                                                                                  
 ------ ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
  62     Parameter #2 $next (callable(Psr\Http\Message\RequestInterface): Http\Promise\Promise) of method Bitbucket\HttpClient\Plugin\Authentication::handleRequest() should   
         be contravariant with parameter $next (callable(): mixed) of method Http\Client\Common\Plugin::handleRequest()                                                        
  62     Parameter #3 $first (callable(Psr\Http\Message\RequestInterface): Http\Promise\Promise) of method Bitbucket\HttpClient\Plugin\Authentication::handleRequest() should  
         be contravariant with parameter $first (callable(): mixed) of method Http\Client\Common\Plugin::handleRequest()                                                       
 ------ ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
GrahamCampbell commented 4 years ago

NB This syntax for callable typing is standard, and is agreed between both PHPStan and Psalm (and others), and understood by PHPStorm. In the absence of any universality accepted specification of phpdoc syntax, I think this is the best I can say.