phpsymfonydocblockspsalm-php

How to resolve Pslam MixedReturnTypeCoersion


ERROR: MixedReturnTypeCoercion - src/Entity/User.php:98:16 - The type 'non-empty-array<array-key, "ROLE_USER"|mixed>' is more general than the declared return type 'array<array-key, string>' for App\Entity\User::getRoles (see https://psalm.dev/197)
        return array_unique($roles);

I am running psalm in a symfony project and getting the above Error, below is the method definition but I have no idea what to adjust in order to fix the error.

/**
     * @see UserInterface
     * @psalm-return array<array-key, string>
     * @return string[]
     */
    public function getRoles(): array
    {
        $roles = $this->roles;
        // guarantee every user at least has ROLE_USER
        $roles[] = 'ROLE_USER';

        return array_unique($roles);
    }

Solution

  • here are two solutions to this issue. It is an implementation of orklah answer.

    The first solution is to declare array_unique() return value as an array of string:

        /** 
         * @see UserInterface
         *
         * @return string[]
         * @psalm-return array<array-key, string>
         */
        public function getRoles(): array
        {
            $roles = $this->roles;
            // guarantee every user at least has ROLE_USER
            $roles[] = 'ROLE_USER';
    
            /** @psalm-var array<array-key, string> $roles */
            $roles = array_unique($roles);
    
            return $roles;
        }
    

    Please note that Psalm allows the use of list<string> for string[]. list is an array<int, string> which first key is 0 :

        /** 
         * @see UserInterface
         *
         * @return string[]
         * @psalm-return list<string>
         */
        public function getRoles(): array
        {
            $roles = $this->roles;
            // guarantee every user at least has ROLE_USER
            $roles[] = 'ROLE_USER';
    
            /** @psalm-var list<string> $roles */
            $roles = array_unique($roles);
    
            return $roles;
        }
    

    The second solution is more of a work-around: suppress the warning.

        /**
         * @see UserInterface
         *
         * @return string[]
         * @psalm-return array<array-key, string>
         *
         * @psalm-suppress MixedReturnTypeCoercion
         */
        public function getRoles(): array
        {
            $roles = $this->roles;
            // guarantee every user at least has ROLE_USER
            $roles[] = 'ROLE_USER';
    
            return array_unique($roles);
        }