-
Notifications
You must be signed in to change notification settings - Fork 668
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
Psalm complains when passing an array with extra properties #5379
Comments
I found these snippets: https://psalm.dev/r/440c1cd447<?php
/**
* @psalm-template K
* @psalm-template V
*/
class Collection {}
/**
* @psalm-suppress UnusedParam
* @psalm-param Collection<int, array{code: string}> $items
*/
function test(Collection $items): void {}
/** @var Collection<int, array{code: string, value: string}> $value */
test($value);
https://psalm.dev/r/0ae6a8d4a3<?php
/**
* @psalm-suppress UnusedParam
* @psalm-param array<int, array{code: string}> $items
*/
function test(array $items): void {}
/** @var array<int, array{code: string, value: string}> $value */
test($value);
|
Generics are invariant, so you cannot pass Collection of a subtype where Collection of a supertype is expected. You would have to mark corresponding type parameter covariant for that to work: https://psalm.dev/r/015291e4ca |
I found these snippets: https://psalm.dev/r/015291e4ca<?php
/**
* @psalm-template K
* @psalm-template-covariant V
*/
class Collection {}
/**
* @psalm-suppress UnusedParam
* @psalm-param Collection<int, array{code: string}> $items
*/
function test(Collection $items): void {}
/** @var Collection<int, array{code: string, value: string}> $value */
test($value);
|
Thanks for the pointer! I don't understand why generics are not covariant by default, though: what's a use case when covariance would not be desirable? |
Because of this: #1603 |
The same example is also discussed in the docs: https://psalm.dev/docs/annotating_code/templated_annotations/#template-covariance |
Thank you, I understand the issue now. But can't the covariance / contravariance be inferred from the use case though: when it's used as a parameter or as a return type? Why does it works with plain arrays? |
Array that you receive as a parameter is copied once you change it. It does not affect the array that was passed. |
Repro: https://psalm.dev/r/440c1cd447
Result:
If I change
Collection
for anarray
, it works fine: https://psalm.dev/r/0ae6a8d4a3The text was updated successfully, but these errors were encountered: