Дженерики еще не подвезли, которые бы сделали это возможным
Используйте коллекции (из Симфони или Ларавел возьмите), если хотите, чтобы был некий контроль за типом, но и они, опять же, не будут полноценно контролировать тип элемента сами по себе.
class Bar
{
/** @var ArrayCollection|Bar[] */
public ArrayCollection $props;
}
Для решения вашей задачи нужен еще один виток развития языка :)
НЕсуществующий код!class ArrayCollection<T>
{
public getElement(): <T>;
public addElement(<T> $element): void;
}
class Bar
{
public ArrayCollection<Bar> $barCollection;
}
Единственное, можно свои коллекции прокачать на проверку типа при создании объекта этой коллекции