Generics on Iterators

Hi all, I haven't used PHP in a while, and it looks like PHPStorm is getting very good with Generic Support.

I feel like this should be supported in 2022.2 but I'm not sure if it is - maybe I'm not marking up something correctly.

I have a class called Iterator

/**
* @template X
*/
class EntityList extends Construct implements Iterator{
/** @return X **/
function first() {}

}

And then another function which gets an EntityList:

/** @return \EntityList<Users> **/
function where(array $filters){}

So 

$users = Users::where([]); //Returns EntityList<Users>. 
$firstUserId = $users->first()->id //Correctly infers first as Users class.

foreach($users as $user){
/*
However $user is not detected as a Users object in either
closures or foreach
*/
}

Do I need to mark things up differently?

Thank you

4 comments
Comment actions Permalink

Generally that should work: https://youtrack.jetbrains.com/issue/WI-62323. Can't unfortunately advise why exactly this doesn't work without a full code example. Perhaps you can share one using https://psalm.dev/ that would show that generics are correctly inferred? 

0
Comment actions Permalink

Thanks Dmitry.

I'm not sure I can provide code without dumping out an entire framework. I will try and test on a smaller codebase and see if it's reproducible.

An example in use. 

In this case the class Users has the method "where" defined in PHPDoc.

* @method static \EntityModel<Users> where(array $filters)

And EntityModel is a generic with Template X, which has select() method described as such

(I have modified the @return to be just EntityList<X> as well, same result).

Then EntityList is described as in my original post: 

/**
* @template X
*/
class EntityList extends Construct implements Iterator{

And first() is described as in original post as well.

And calling Users::where([])->first() as below DOES correctly infer the end type:

But as soon as I throw it in a foreach it fails:

I will try to reproduce this on a smaller project, gimme a bit!

0
Comment actions Permalink

Dmitry Tronin I have uploaded a sample project here which reproduces the issue:

https://github.com/dredgy/GenericTest

0
Comment actions Permalink

Thanks. Tried to make this work but without success. I've submitted this as a new report on our tracker: https://youtrack.jetbrains.com/issue/WI-69063. You can vote for it in order to get notified about its updates.

0

Please sign in to leave a comment.