Skip to content

Add SelectQueryFindListReturnTypeExtension for find('list')->toArray()#64

Merged
rochamarcelo merged 5 commits intoCakeDC:4.next-cake5from
dereuromark:feature/find-list-return-type
Mar 27, 2026
Merged

Add SelectQueryFindListReturnTypeExtension for find('list')->toArray()#64
rochamarcelo merged 5 commits intoCakeDC:4.next-cake5from
dereuromark:feature/find-list-return-type

Conversation

@dereuromark
Copy link
Copy Markdown
Collaborator

Summary

This PR adds a PHPStan dynamic return type extension that provides proper type inference for find('list')->toArray().

Problem

Currently, when using find('list'), PHPStan infers the return type as array<array|EntityInterface>, but find('list') actually returns array<int|string, string>. This causes developers to need @var annotations:

/** @var array<int, string> $roles */
$roles = $this->Roles->find('list', fields: ['uuid'])->toArray();

Without the annotation, PHPStan reports varTag.type errors.

Solution

The SelectQueryFindListReturnTypeExtension detects find('list') in the method call chain before toArray() and returns the correct type array<int|string, string>.

Features:

  • Detects find('list') anywhere in the method chain
  • Works with chained queries: find('list')->where([...])->orderBy([...])->toArray()
  • Returns null for non-list finders to preserve default behavior

Tests

Added test cases for:

  • Basic find('list')->toArray() usage
  • Chained method calls (where, orderBy, limit)
  • Verification that values are correctly typed as strings

Example

Before (with annotation):

/** @var array<int, string> $list */
$list = $table->find('list')->toArray();

After (no annotation needed):

$list = $table->find('list')->toArray();
// PHPStan knows this is array<int|string, string>

This extension provides proper return type inference for find('list')->toArray(),
returning array<int|string, string> instead of the generic entity array type.

The extension:
- Detects find('list') in the method chain before toArray()
- Works with chained queries (where, orderBy, limit, etc.)
- Returns null for non-list finders to preserve default behavior

Fixes the common issue where $roles = $table->find('list')->toArray()
would require a @var annotation to suppress PHPStan varTag.type errors.
@dereuromark
Copy link
Copy Markdown
Collaborator Author

"The job was not started because your account is locked due to a billing issue"

@steinkel
Copy link
Copy Markdown
Member

let me check that...

@rochamarcelo
Copy link
Copy Markdown
Contributor

It looks good.

Have you checked what happens when groupField is used $table->find('list', groupField: 'category_id'); ? We probably should handle that too.

When find('list', groupField: '...') is used, the return type
changes to array<int|string, array<int|string, string>> instead
of the simple array<int|string, string>.
@steinkel
Copy link
Copy Markdown
Member

let me check that...

fixed

@dereuromark
Copy link
Copy Markdown
Collaborator Author

The phpstan fail is not mine, and fixing it would require 5.3+ bump or silencing.
I opened a ticket for now: #65

@dereuromark
Copy link
Copy Markdown
Collaborator Author

@rochamarcelo Both ways are now supported.

@rochamarcelo rochamarcelo merged commit c5d1169 into CakeDC:4.next-cake5 Mar 27, 2026
6 checks passed
@dereuromark dereuromark deleted the feature/find-list-return-type branch March 27, 2026 17:07
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