Skip to content

Patch/inconsistent return type #56349

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from

Conversation

susantp
Copy link

@susantp susantp commented Jul 20, 2025

Laravel Version

12.20.0

PHP Version

8.4.10

Database Driver & Version

No response

Description

In the current implementation of the shift method in Laravel's Illuminate/Collection, the return type indicated in the PHPDoc is inconsistent with the actual return type in a specific case:

/**
 * Get and remove the first N items from the collection.
 *
 * @param int<0, max> $count
 * @return static<int, TValue>|TValue|null
 *
 * @throws \InvalidArgumentException
 */
public function shift($count = 1)
{
    if ($count < 0) {
        throw new InvalidArgumentException('Number of shifted items may not be less than zero.');
    }

    if ($this->isEmpty()) {
        return null;
    }

    if ($count === 0) {
        return new static;
    }

    if ($count === 1) {
        return array_shift($this->items); // <-- returns a single item directly, not wrapped in a Collection instance.
    }

    $results = [];
    $collectionCount = $this->count();

    foreach (range(1, min($count, $collectionCount)) as $item) {
        $results[] = array_shift($this->items);
    }

    return new static($results);
}

In the above code, when $count === 1, the method returns a single item (TValue), not wrapped in a Collection instance, which causes inconsistency relative to the return type mentioned in the PHPDoc (static<int, TValue>|TValue|null).

Proposed Code Change:

Modify the $count === 1 condition to consistently return a Collection instance:

if ($count === 1) {
    return new static([array_shift($this->items)]);
}

Benefits of Change:

  • Ensures strict type consistency.
  • Simplifies handling of return types downstream.
  • Aligns actual behavior with documented return type.

Additional Note:

  • Existing behavior returning a single item directly could be considered convenient in some contexts, but type safety and predictability favor consistently returning a Collection instance.

Laravel Version Affected: Latest (as of July 2025)

Suggested Labels: bug, consistency, collections, type-safety


Steps To Reproduce

  • Create a Laravel Collection instance with at least one item.
  • Call the shift() method with argument 1.
  • Observe that the method returns the first item directly, not wrapped in a Collection instance.
  • Call the shift() method with argument > 1.
  • Observe that the method returns a Collection instance.
  • Compare the return types between both cases.

PR raised to resolve this issue: #56348

@bert-w
Copy link
Contributor

bert-w commented Jul 25, 2025

The type is correct? it can return TValue which is one of the collection's elements. Also this is a breaking change so it should target the master branch.

Copy link
Member

@GrahamCampbell GrahamCampbell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your reasoning is incorrect. The doc says collection OR TValue.

@susantp susantp closed this Jul 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants