Skip to content

Incorrect docblock for EnumeratesValues::ensure() #48443

Closed
@wimski

Description

@wimski

Laravel Version

10.23.1

PHP Version

8.2.3

Database Driver & Version

No response

Description

The @param and @return declarations in the docblock of the lluminate\Collections\Traits\EnumeratesValues::ensure() method are incorrect.

/**
* Ensure that every item in the collection is of the expected type.
*
* @template TEnsureOfType
*
* @param class-string<TEnsureOfType> $type
* @return static<mixed, TEnsureOfType>
*
* @throws \UnexpectedValueException
*/
public function ensure($type)

@param

Situation

The documentation says the following about the $type parameter:

Primitive types such as string, int, float, bool, and array may also be specified:

return $collection->ensure('int');

https://laravel.com/docs/10.x/collections#method-ensure

Issue

The usage with primitive type strings doesn't match the class-string<TEnsureOfType> type-hint and static analysis tools (like PHPStan) will complain about this (and rightly so).

Solution

Since you can't type-hint "a string representation of a primitive type" (so far at least), the only solution would be to create separate methods for all primitive types (ensureInt, ensureBool, etc.).

@return

Situation

The key type is hinted as mixed, although a template TKey of array-key is available.

Issue

This makes a collection lose it's key type after applying the ensure method.

Solution

/*
 * @return static<TKey, TEnsureType>
 */

Steps To Reproduce

  1. Install Laravel
  2. Install PHPStan
  3. Create a file app/Example.php with the following code:
<?php

declare(strict_types=1);

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;

class Example
{
    /**
     * @param  Collection<array-key, mixed> $collection
     * @return void
     */
    public function paramIssue(Collection $collection): void
    {
        $collection->ensure('int');
    }

    /**
     * @param  array<int, Model> $array
     * @return Collection<int, Model>
     */
    public function returnIssue(array $array): Collection
    {
        return collect($array)->ensure(Model::class);
    }
}

Running static analysis will generate the following errors:

 ------ -----------------------------------------------------------------------------------------------------------------------------------
  Line   app/Example.php
 ------ -----------------------------------------------------------------------------------------------------------------------------------
  18     Parameter #1 $type of method Illuminate\Support\Collection<(int|string),mixed>::ensure() expects class-string<int>, string given.
  27     Method App\Example::returnIssue() should return
         Illuminate\Support\Collection<int, Illuminate\Database\Eloquent\Model> but returns
         Illuminate\Support\Collection<mixed, Illuminate\Database\Eloquent\Model>.
 ------ -----------------------------------------------------------------------------------------------------------------------------------

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions