Background
I do have classes (here: ClassA
and ClassB
) that shall be tested. As these classes are similar, I created an abstract test-class that implements an interface.
Problem
At level 7, PhpStan is unhappy and reports these issues:
Call to an undefined method object::getId()
Call to an undefined method object::getName()
I do know that it is unclear which object is calling the methods and thus the issue is reported and I know that the solution is by using GENERICS.
Question
I just started with the use of generics, I have no clue how to solve this correctly.
Anybody so kind to support me here? Thanks!
Code
see PhpStan Playground.
REMARK: The example here is simplified to support the discussion.
<?php
// ---------------------------------------- CLASSES
class ClassA {
public function getId(): int {
return 123;
}
}
class ClassB {
public function getName(): string {
return 'abc';
}
}
// ---------------------------------------- TESTS
/**
* @template T
*/
interface InterfaceForTest {
public function getClassName(): string;
}
/**
* @template T
* @implements InterfaceForTest<T>
*/
abstract class AbstractClassTest implements InterfaceForTest {
public function createObject(): object
{
$class = $this->getClassName();
$object = new $class();
return $object;
}
}
/**
* @template T
* @extends AbstractClassTest<T>
*/
class ClassATest extends AbstractClassTest {
public function getClassName(): string
{
return ClassA::class;
}
public function testA(): void
{
$obj = $this->createObject();
assert($obj->getId() === 123); // makes PHPStan unhappy at level 7
}
}
/**
* @template T
* @extends AbstractClassTest<T>
*/
class ClassBTest extends AbstractClassTest {
public function getClassName(): string
{
return ClassB::class;
}
public function testA(): void
{
$obj = $this->createObject();
assert($obj->getName() === 'abc'); // makes PHPStan unhappy at level 7
}
}