vscode-intelephense
vscode-intelephense copied to clipboard
Doesn't know the type when iterate iterable
Describe the bug
When doing foreach on iterables built in php, intelepehense doesn't know the type. Example DOMNodeList iterates to DOMElement|DOMNode|DOMNameSpaceNode|null
To Reproduce
$dom = new \DOMDocument();
$xpath = new \DOMXPath($dom);
$links = $xpath->query('.//a[@href]');
assert($links !== false);
foreach ($links as $link) {
var_dump($link);
exit;
}
Expected behavior $link is DOMElement|DOMNode|DOMNameSpaceNode|null
Screenshots
Platform and version OS and Intelephense version.
I think the upstream stubs could be improved to solve this https://github.com/JetBrains/phpstorm-stubs/blob/master/dom/dom_c.php#L1340
I think it's not totally fixed.
DOMNodeList iterates to DOMElement|DOMNode|DOMNameSpaceNode
You only show \DOMNode|\DOMNameSpaceNode
When using query, it looks to be the correct type, but when using DOMDocument::getElementsByTagName which also return a DOMNodeList, PHPStan says the type is DOMElement, but intelephense says only \DOMNode|\DOMNameSpaceNode
$dom = new \DOMDocument();
$xpath = new \DOMXPath($dom);
$links = $xpath->query('.//a[@href]');
assert($links !== false);
foreach ($links as $link) {
var_dump($link);
}
$links = $dom->getElementsByTagName('a');
assert($links !== false);
foreach ($links as $link) {
var_dump($link);
}
DOMElement extends DOMNode so it is redundant to have a union here. The upstream stubs need further work to make them templated. You're welcome to use phpstan's stubs as a guide and submit a PR to the upstream stubs package.
Except that i'm using DOMElement only method :
if (!$img->hasAttribute('src')) {
continue;
}
and intelephense shows an error here
The DOMNodeList class would need a template and then the getElementsByTagName would need to be changed to return DOMNodeList<DOMElement>. It's an upstream issue with the stubs.
This seems similar, and their solution is to first check it's type before calling the property. I tested, and this does indeed seem to work, though it seems a little silly to me that this would be necessary. I guess it's technically correct though, so good enough for me.