I cannot figure how to annotate an array returned from API Response.
Response have a structure:
array{'totalCount': numeric-string, $vehicleType: array}
Instead of variable $vehicleType
there can be different keys. List of all possible keys ($vehicleType) I have stored in Enum named VehicleType.
Here is an example of API reponse:
{
'totalCount': '2',
'car': [
{'id': '14', 'brand': 'Ford'},
{'id': '15', 'brand': 'Honda'}
]
}
Instead of 'car' from example I want to declare that it would be a specific string. Preferably I would like to declare all possible variations of that string (from my VehicleType Enum).
PSALM gives me errors, because I cannot declare return array of a method right.
Because keys in PHPDoc Array shapes can be only simple strings. More than that - it doesn't support enumeration (with '|') in it. Like 'car'|'airplane'
Example #1 (using Array shapes with 'value-of' in key)
The most obvious and intuitive way - simply does not work. Because of the statement above - keys in PHPDoc Array shapes can be only simple strings
* @return array{'totalCount': numeric-string, value-of<VehicleType>: array}
Example #2 (using Array shapes with generic as key)
* @template ModelKey of value-of<VehicleType>
class ...
....
* @return array{'totalCount': numeric-string, ModelKey: array}
function...
This way PSALM sees ModelKey just as a string 'ModelKey'
Example #3 - Using General arrays I understand that I can declare an multi-element as follows:
@return array<value-of<VehicleType>, array>
This obviously is not a solution:
'totalCount'
element is not declared at all.- This tells PSALM that this array can contain multiple elements with keys from VehicleType enum, instead of only one
Example #4 - Combination of General arrays and Generics Using generics this way:
/** @template TotalElement of array{'totalCount': numeric-string}
* @template VehicleElement of array<value-of<VehicleType>, array>
* @template ApiResponseArray of array{TotalElement, VehicleElement}
*/
class
...
/** @return ApiResponseArray */
public function ...
Makes it even worse - besides problem #2 from previous example we will not have an array with multiple keys, but array with separated arrays
Link: https://phpstan.org/writing-php-code/phpdoc-types I would really like a help with this, not even sure right now if it even possible. Currently my thought about this:
- Since I couldn't find on internet how to solve this now I tend to think I will not be able to use generated strings as keys in Array shapes;
- I just might have to declare return array as more general. Just using
string
instead ofvalue-of<VehicleType>
; @return array{'keyOne'|'keyTwo': array}
. I will repeat: even this is not working;- Converting Arrays to some Objects and working with them seems like a stupid hack and an overkill