You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Well, from a static analysis point of view, there is two possibilities:
The analysis tool try to infer the type of T from the value. This is delicate because there is a granularity of type to consider. For example, new ValueHolder(21); could very well be a ValueHolder<21>. On the opposite direction, it could be a ValueHolder<scalar> where the first value happen to be a literal int. (this example could make more sense with objects where we push a Child class and the tool has to decide whether it's a ValueHolder<Child> or a ValueHolder<Parent_> with a Child as first element)
The analysis tool can require the user to document the type of the templated class. This is the choice made by psalm and phpstan if I'm not mistaken. Psalm will consider T = empty in the absence of an explicit /** @var ValueHolder<int> */
This maps to what would happen in Java (based on my Java knowledge from 5 years ago!) ...
intHolder = newValueHolder<int>();
@orklah raises an interesting point when inferring the type. Is new ValueHolder(new Dog()); holding Dog or Animal. Psalm assumes Dog, which I tend to agree with.
Either way the ambiguity suggests adds weight the argument that the type should be explicitly stated.
The description in https://github.com/DaveLiddament/php-generics-standard#constructor is a bit unclear to me. If you are passing a literal integer value, it's obvious that
T = int
, but what if the value is dynamic?In this case,
$foo
can beint
ornull
at runtime. However, I would assume that the actual inferred type isT = ?int
. Is that correct?If it is, then what about this variant?
Here,
$foo
is known to beint
, but only through flow-sensitive type analysis. WouldT = int
here?The text was updated successfully, but these errors were encountered: