22.01.2025・TechStuff
22.01.2025・TechStuff

PHPStan: unspecified value in iterable

Fabian Blechschmidt
Method Some\ClassDefinition::write() has parameter $record with no value type specified in iterable type array.

I got this error yesterday and it took hours until I figured out the problem.

Why you ask? Because the class looked like this:

<?php

declare(strict_types=1);

namespace Some;

/**
 * @phpstan-type LogRecord array{
 *     message: string,
 *     context: array,
 *     level: 100|200|250|300|400|500|550|600,
 *     level_name: 'ALERT'|'CRITICAL'|'DEBUG'|'EMERGENCY'|'ERROR'|'INFO'|'NOTICE'|'WARNING',
 *     channel: string,
 *     datetime: \DateTimeImmutable,
 *     extra: array,
 *     formatted: mixed
 * }
 */
class ClassDefinition
{
    /**
     * @param LogRecord $record
     */
    public function write(array $record): void
    {
        // do something
    }
}

My impression was: why is $record a problem? It has a type! After trying a simpler example at PHPStan’s playground, I found the problem:

/**
 * @phpstan-type LogRecord array{
       [...]
 *     context: array,
       [...]
 *     extra: array,
       [...]
 * }
 */

While writing this blogpost I tried it again, and PHPStan is of course telling you, what the problem is:

Class Some\ClassDefinition has type alias LogRecord with no value type specified in iterable type array.

I just didn’t see it.

Hope that helps!