0

I have the simplified code example from my library, to which psalm, for reasons I don't understand, outputs warnings.

class Example {
    public const C_1 = 'val1';
    public const C_2 = 'val2';
    public const C_3 = 'val3';

    /**
    * @param self::C_1 | self::C_2 $c
    */
    public function __construct(string $c)
    {
       if (!in_array($c, [self::C_1, self::C_2], true)) {
            throw new InvalidArgumentException('Unsupported value');
        }
    }
}

On if (!in_array($c, [self::C_1, self::C_2], true)) line displays a warning with the type DocblockTypeContradiction and the message Docblock-defined type "val1" for $c is always string(val1).

As I understand it, psalm requires remove the check if (!in_array($c, [self::C_1, self::C_2], true)), since constants are already checked by psalm. But what if a user who will use my library will not use psalm in his project? How then to check the correctness of the passed argument to the constructor?

Sorry for the bad English. I hope I was able to explain the problem.

XYZ
  • 155
  • 1
  • 5

1 Answers1

1

The issue is that you have a different type declaration in @param than what your method signature says.

The check with in_array absolutely makes sense because as you said not everyone will be using Psalm as a guarantee.

One way is to just change the @param annotation to let it know you're passing a string, which psalm is okay with:

/**
 * @param string $c
 */

But this is a but superfluous as PHP is already making sure that we have a string there, so just removing the doc block works just as well.

ArSeN
  • 5,133
  • 3
  • 19
  • 26