如何声明可遍历类型?

How To Declare Traversable Type?

PHP 中有多个类型提示,现在 PHP 8 中更多,Psalm 中更多。但是 声明 类型,而不是暗示预期的类型呢?

我有一个interface Collection extends Traversable,我需要声明它是Abc类型的遍历。我该怎么做,以便 PHPDoc 或 Psalm 知道当我遍历 Collection 的实例时,每个元素的类型都是 Abc?

换句话说,我需要在接口层面,保证断言总是通过:

function doWithItems(Collection $items): void
{
    foreach ($items as $item) {
        assert($item instanceof Abc);
    }
}

我的代码中没有可用的接口示例(这些可能很难正确实现),但由于 Psalm 在 Traversable 上实现了 interface Traversable<TKey, TValue> template,它会是这样的:

/**
 * @extends Traversable<array-key,Abc>
 */
interface Collection extends Traversable

我的代码中使用 Doctrine Collections 的绝对有效的 class 级示例(它具有非常全面的 Psalm 支持,您可以查看源代码了解他们是如何做到的):

/**
 * @extends ArrayCollection<array-key, ShowInterface>
 */
final class Shows extends ArrayCollection