1

Is it possible to type hint a parameter directly inline during a function call?

public function load(ObjectManager $manager)
{
    $product = $this->createProduct(
        "T-SHIRT",
        $this->getReference('brand-4') /** @var Brand <=== NOT WORKING */ 
    );
    $manager->persist($product);
    $this->addReference('product-1', $product);
}

/**
 * @param string $name
 * @param Brand  $brand
 */
private function createProduct($name, $brand)
{
    $product = new Product();
    $product
        ->setName($name)
        ->setBrand($brand) // <== this setter needs a Brand entity
    ;

    // [...]
}

Of course phpstan is giving me an error because getReference returns an object and the function expects a Brand object:

Parameter #2 $brand of method AppBundle\DataFixtures\ORM\ProductFixtures::createProduct() expects AppBundle\Entity\Brand, object given.

I would NOT like to explicity declare a variable like this:

/** @var Brand */
$brand = $this->getReference('brand-4');
$product = $this->createProduct(
    "T-SHIRT",
    $brand
);

It would save me a lot of time!

9
  • 1
    Why not changing createProduct hint? Commented Mar 5, 2020 at 16:42
  • Because createProduct will call setBrand on a newly created Product object and it expects a Brand entity. Commented Mar 5, 2020 at 16:43
  • 1
    I see, the getReference returns various types of class according to reference, so you cannot hint its return type. But you are sure that it will return a Brand object from brand-4 so you want a way to hint this type in-line. Commented Mar 5, 2020 at 16:49
  • @bravemaster exactly! Commented Mar 5, 2020 at 16:50
  • A workaround would be to change the createProduct hint anyway, and use instanceof in it to assert you have a Brand but I guess it's not much better than defining a variable. On another hand it could allow you to make sure getReference's return is indeed a Brand and manage the errors. Commented Mar 5, 2020 at 16:50

1 Answer 1

1

I had the same problem implementing a generic like structure. This solution works when you want to override method signature. You can accomplish this using @method doc comments but you need 2 classes for it:

class AbstractRepository {
  /**
   * @param mixed $id
   * @return object
   */
  public function getReference($id) {
     /* ... */
  }
}

/**
 * @method ConcreteResult getReference($id)
 */
class ConcreteRepository extends AbstractRepository {

}

$repo = new ConcreteRepository();
$repo->getReference(123); // Has ConcreteResult return type

This works in PHPStorm for example. I have not checked if it works with PHPStan.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.