psalm icon indicating copy to clipboard operation
psalm copied to clipboard

NonInvariantDocblockPropertyType false positive when child property uses psalm-type

Open MauricioFauth opened this issue 2 years ago • 1 comments

It works if I declare the same type for both properties: https://psalm.dev/r/f3c5eed362

But it does not work when using @psalm-type: https://psalm.dev/r/d5ddb3e4fc

Also: https://psalm.dev/r/6facf65dd6

See https://github.com/vimeo/psalm/issues/6575#issuecomment-1258418112:

This may be a different bug where aliases are wrongly checked when looking at invariance.

  • Related to #6575

MauricioFauth avatar Sep 26 '22 19:09 MauricioFauth

I found these snippets:

https://psalm.dev/r/f3c5eed362
<?php

abstract class Father {
    /** @var array<string, string> */
    public array $a = [];
}

class Child extends Father {
    /** @var array<string, string> */
    public array $a = [
    	'key' => 'value',
	];
}
Psalm output (using commit 028ac7f):

No issues!
https://psalm.dev/r/d5ddb3e4fc
<?php

/**
 * @psalm-type FatherType = array<string, string>
 */
abstract class Father {
    /** @var FatherType */
    public array $a = [];
}

/**
 * @psalm-import-type FatherType from Father
 */
class Child extends Father {
    /** @var FatherType */
    public array $a = [
    	'key' => 'value',
	];
}
Psalm output (using commit 028ac7f):

ERROR: NonInvariantDocblockPropertyType - 16:18 - Property Child::$a has type type-alias(Father::FatherType), not invariant with Father::$a of type array<string, string>
https://psalm.dev/r/6facf65dd6
<?php

declare(strict_types=1);

namespace Common;

/**
 * @psalm-type MessageTemplatesType = array<string, string>
 */
abstract class AbstractClass
{
    /**
     * @psalm-var MessageTemplatesType Validation error message templates to be used when validators detect
     *         errors that needs showing.
     */
    protected array $messageTemplates = [];
}

namespace App;

use Common\AbstractClass;

/**
 * @psalm-import-type MessageTemplatesType from AbstractClass
 */
class ConcreteClass extends AbstractClass
{
    /** @psalm-var MessageTemplatesType */
    protected array $messageTemplates = [
        'not_same'  => 'Security validation failed. Please try again.',
        'not_found' => 'We could not find a Use a lasting power of attorney account ' .
            'with that email address and password. Check your details and try again.',
    ];
}
Psalm output (using commit 028ac7f):

ERROR: NonInvariantDocblockPropertyType - 29:21 - Property App\ConcreteClass::$messageTemplates has type type-alias(Common\AbstractClass::MessageTemplatesType), not invariant with Common\AbstractClass::$messageTemplates of type array<string, string>

psalm-github-bot[bot] avatar Sep 26 '22 19:09 psalm-github-bot[bot]

Just came accross the same issue: https://psalm.dev/r/6e05abde32

Hikariii avatar Feb 10 '23 11:02 Hikariii

I found these snippets:

https://psalm.dev/r/6e05abde32
<?php

/**
 * @psalm-type dataType = array<array-key, mixed>
 */
abstract class A {
    /** @psalm-var dataType */
    protected array $data = [];
}

/**
 * @psalm-import-type dataType from A
 */
class B extends A {
    /** @psalm-var dataType */
    protected array $data = [ 'test' ];
}
Psalm output (using commit d66981a):

ERROR: NonInvariantDocblockPropertyType - 16:21 - Property B::$data has type type-alias(A::dataType), not invariant with A::$data of type array<array-key, mixed>

psalm-github-bot[bot] avatar Feb 10 '23 11:02 psalm-github-bot[bot]