Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PHPStan complains about return type of instantiateWith in a PersistentProxyObjectFactory factory #721

Open
marien-probesys opened this issue Nov 7, 2024 · 7 comments
Labels
bug Something isn't working

Comments

@marien-probesys
Copy link
Contributor

Hi,

I use PHPStan to verify the typing in my application. I have an issue when using the instantiateWith() method in a PersistentProxyObjectFactory factory.

instantiateWith() is declared in the ObjectFactory and must return an object of the template class T. However, when inheriting from the PersistentProxyObjectFactory class, T becomes T&Proxy<T>. Meaning that PHPStan expects instantiateWith() to return a T&Proxy<T> object.

namespace App\Tests\Factory;

use App\Entity\MyEntity;
use Zenstruck\Foundry\Persistence\PersistentProxyObjectFactory;

/**
 * @extends PersistentProxyObjectFactory<MyEntity>
 */
final class MyEntityFactory extends PersistentProxyObjectFactory
{
    protected function initialize(): static
    {
        // The return type of instantiateWith is correct, but PHPStan expects a MyEntity&Proxy<MyEntity> and fail.
        return $this->instantiateWith(function (array $attributes, string $class): MyEntity {
            $myEntity = new MyEntity();

            // …

            return $myEntity;
        });
    }

    // …
}
@nikophil
Copy link
Member

nikophil commented Nov 7, 2024

Hi @marien-probesys

which Foundry's (and PHPStan) version are you using?
I've recently added specific phpdoc for this case

@marien-probesys
Copy link
Contributor Author

Hi @nikophil, thanks for your answer. I'm using PHPStan 1.12.11 (the latest version of v1) and Foundry 2.2.2.

I'm sorry I made a mistake in my explanations: the problem is not with the instantiateWith() method directly, but with its callable parameter $instantiator. It is its return type which is wrong! (so the InstantiatorCallable type defined at the top of the file)

If you need it, I can create a minimal project tomorrow in order to reproduce the problem.

@marien-probesys
Copy link
Contributor Author

I've created a repository to reproduce the problem: https://github.com/marien-probesys/foundry-721

You can see the error here: https://github.com/marien-probesys/foundry-721/actions/runs/11915667680/job/33206464561

And the factory: https://github.com/marien-probesys/foundry-721/blob/main/src/Factory/PostFactory.php

@nikophil
Copy link
Member

thanks for your reproducer! I'll soon check this

@nikophil
Copy link
Member

Hi, I really don't know what to do to make PHPStan happy here 🤔

you code seems OK, but the phpdoc for ObjectFactory::instantiateWith() seems also OK 🤔

@kbond any thoughts?

@kbond
Copy link
Member

kbond commented Dec 13, 2024

That's a bummer. Feels like it's because the string in the closure isn't being considered class-string<Post>?

@nikophil
Copy link
Member

nope, it is because of the proxy: if the factory extends from PersistentObjectFactory instead of PersistentProxyObjectFactory, phpstan is happy

@nikophil nikophil added the bug Something isn't working label Dec 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Development

No branches or pull requests

3 participants