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

Form is not subtype of native type FormInterface #350

Open
daniel-calderini opened this issue Apr 24, 2023 · 6 comments
Open

Form is not subtype of native type FormInterface #350

daniel-calderini opened this issue Apr 24, 2023 · 6 comments

Comments

@daniel-calderini
Copy link

Starting with version 1.3.0 of phpstan/phpstan-symfony, the following code is not valid anymore.

// src/Controller/DefaultController.php

use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormInterface;

...

/** @var Form&FormInterface $form */
$form = $this->createForm(...);

Until version 1.2.25, no problems were reported here, but now I get the following error:

PHPDoc tag @var with type Symfony\Component\Form\Form is not subtype of native type Symfony\Component\Form\FormInterface.
@ondrejmirtes
Copy link
Member

This is weird. Can you please create a small reproducing repository?

@nicodemuz
Copy link

I had the same issue. I ended up removing the phpdoc and surrounding some code with an if statement with $form instanceof Form.

@Wirone
Copy link
Contributor

Wirone commented Jul 4, 2024

We have the same issue currently (1.4.5 + PHPStan 1.11.6). Consider simplified code:

services:
  # Interface
  Foo\ClientFactory: '@Foo\ApplicationClientFactory'

  # Implementation
  Foo\ApplicationClientFactory: ~

then, when we do something like:

/** @var \Foo\ClientFactory $factory */
$factory = $container->get(\Foo\ClientFactory::class);

we get an error:

PHPDoc tag @var with type Foo\ClientFactory is not subtype of type Foo\ApplicationClientFactory.

which does not make sense. We fetch ClientFactory from DI container, it's aliased to ApplicationClientFactory implementation that satisfies the interface, so of course interface is not a subtype, it's super type.

@ondrejmirtes
Copy link
Member

PHPStan doesn't want you to use a less specific type in the PHPDoc, because it already knows a more specific type.

More often than not, you can simply delete this @var.

They're considered harmful anyway: https://phpstan.org/blog/phpstan-1-10-comes-with-lie-detector#validate-inline-phpdoc-%40var-tag-type

@Wirone
Copy link
Contributor

Wirone commented Jul 4, 2024

But I don't want more specific type here, as the whole idea of interface is interchangeability. In the code, when I fetch ClientFactory (interface) I don't care what implementation comes from DI container, I only want this particular contract, because I don't want to encounter problems when DI alias is changed to other implementation. In our case ApplicationClientFactory has more methods that implemented ClientFactory interface, I don't want developers to be able to use these methods because PHPStan allows it (as it knows the aliased service), rather the other way around - I would expect that static analysis reports usage of methods not defined in the interface.

I believe it's a bug and PHPStan should not narrow the type here. Similar here, I believe I should be allowed to restrict the contract to interface instead of relying on extended implementation.

More often than not, you can simply delete this @var. They're considered harmful anyway: phpstan.org/blog/phpstan-1-10-comes-with-lie-detector

I agree and I don't use @var when I don't need, in this case it's only for IDE which does not have autocompletion for ClientFactory fetched from the container (since get()'s return type is ?object). We use dependency injection mostly, but unfortunately in legacy part of the code there is a lot of direct interaction with DI container.

@ondrejmirtes
Copy link
Member

@Wirone This is a completely different issue than the thing this was originally opened for so please create a separate one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants