How to specify correct return type of function that queries database? #7885
-
I am working with a reusable query function from an external library which takes an arbitrary select query and returns the results as a list: /**
* @param list $params
* @return list<array<array-key, float|int|null|string>>
*/
function query(mysqli $db, string $sql, array $params = []): array
{
$stmt = $db->prepare($sql);
$stmt->execute($params);
return $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
} It can't specify a more exact shape for the returned list because it depends on the query. In my own code, I want to write more specific functions which do specify the shape of the returned array. E.g.: /**
* @return list<array{id: int, name: string}>
*/
function getUsers(mysqli $db, string $role): array
{
return query($db, "SELECT id, name FROM users WHERE role = ?", [$role]);
} However, Psalm doesn't allow this - it produces an Is there a way to specify the exact array shape returned by my |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 3 replies
-
No easy way. It would require parsing the query, mapping its field list to actual DB fields and finding out their types. Theoretically, a plugin could do that. |
Beta Was this translation helpful? Give feedback.
-
I found a way to do it using the /**
* @psalm-type UserList = list<array{id: int, name: string}>
* @return UserList
*/
function getUsers(mysqli $db, string $role): array
{
/** @var UserList */
return query($db, "SELECT id, name FROM users WHERE role = ?", [$role]);
} It's a little more boilerplate-y than I would like, but it works! |
Beta Was this translation helpful? Give feedback.
I found a way to do it using the
@psalm-type
and@var
annotations:It's a little more boilerplate-y than I would like, but it works!