http icon indicating copy to clipboard operation
http copied to clipboard

Psalm TooManyTemplateParams error

Open gdejong opened this issue 4 years ago • 2 comments

Given:

<?php

use React\EventLoop\Factory;
use React\Http\Browser;

$loop = Factory::create();

$browser = new Browser($loop);

$browser->get("");

and running Psalm on it with level 6 or lower, I get the following error:

ERROR: TooManyTemplateParams - test.php:10:1 - React\Promise\PromiseInterface<Psr\Http\Message\ResponseInterface> has too many template params, expecting 0 (see https://psalm.dev/184)
$browser->get("");

I am not sure if this is the right place, but I was wondering if you could shed some light on this. Perhaps Psalm doesn't like the @return PromiseInterface<ResponseInterface> type hint in \React\Http\Browser::get?

Maybe the questions should be, does this project aims to be compatible with Psalm?

gdejong avatar Jan 12 '21 16:01 gdejong

@gdejong Thanks for reporting!

The get() method (any many others) do indeed use a @return PromiseInterface<ResponseInterface,Exception> annotation.

This was added a while ago, i.e. before PHPStan/Psalm started supporting the @template annotation.

Nowadays, we should probably add a @template annotation to the promise component. In this case, the definition in this repository will actually become "valid".

As an alternative, we may also change this annotation to only @return PromiseInterface without using any templates. In this case we would make static analysis tools "happy", but would loose additional information that can be helpful for developers.

Does anybody feel like looking into this and filing a PR?

clue avatar Jan 20 '21 07:01 clue

@clue Question about this:

do indeed use a return PromiseInterface<ResponseInterface,Exception>

For reference, I am using https://github.com/Bocmah/psalm-reactphp-promise-plugin/blob/main/stubs/PromiseInterface.phpstub and have no problems with psalm on level 1 but there is just 1 templated param.

Stub for await also gives me correct return type:

/**
 * @template TResolved
 *
 * @param PromiseInterface<TResolved> $promise
 *
 * @return TResolved
 */
function await(PromiseInterface $promise, LoopInterface $loop, $timeout = null){}

zmitic avatar Aug 12 '21 11:08 zmitic

Promise template types will be added in https://github.com/reactphp/promise/pull/227 (and referenced tickets) soon, so I don't think there's much that needs to be done here. I'll close this ticket for now, but please report back if there's anything that is missing here.

clue avatar Jan 21 '23 11:01 clue

FYI the PR's to address this across our packages are listed here: https://github.com/reactphp/promise/pull/223#issuecomment-1399262314

WyriHaximus avatar Jan 21 '23 14:01 WyriHaximus