I have some template files that have default arguments defined at the top of each file. I can’t get type hinting for these values to work correctly; it just says there is no reference. I am including the WordPress core files in Intelephense, so it understands what a WP_Post
is, I just can’t get it to understanding typing on a multidimensional aray.
I found this GitHub issue which discusses a similar problem, and includes some suggestions on things to try. No matter which method I used, all I can get it to respond with for $args["post"]
is `No references found for ‘post’".
Eventually, I found this WordPress forums thread discussing a similar issue, and links to this WordPress core file which includes the "WordPress-y" way to do document multidimensional arrays, but even this still results in the same message.
That’s how I’ve gotten to this point, but this doesn’t seem to be working correctly either, because the reference pop-up looks quite odd (screenshot below), and doesn’t seem to do anything for type hinting.
<?php
/**
* @var array $args {
* @type WP_Post $post,
* @type string $class,
* @type bool $light,
* @type string $title,
* @type bool $meta,
* @type string $content,
* }
*/
$args = array_merge([
"post" => null,
"class" => "",
"light" => false,
"title" => "",
"meta" => null,
"content" => "",
], $args);
/**
* Retrieve values based on `$post` if set
*/
if ($args["post"] instanceof WP_Post) {
/**
* Set title
*/
if ($args["title"] === "") {
$args["title"] = apply_filters("the_title", $args["post"]->post_title, $args["post"]->ID);
}
/**
* Set meta based on post type
*/
if ($args["meta"] === null && $args["post"]->post_type === "post") {
$args["meta"] = true;
}
/**
* Set content
*/
if ($args["content"] === "") {
$args["content"] = apply_filters("the_content", $args["post"]->post_content);
}
}
?>
Also, I understand that perhaps a class structure would be better, and I will look in to that, but that entails retooling our templating system, so that will take time. For now, I’d like to get type hinting working in this use if at all possible.
2
Answers
First, you can always convince most of the linters what the variable type is by use of
@var
annotation:BUT before you so, please ensure WHY it sees
null|string[]|string|false
and notobject
in the first place. It might be a bug indication or incorrect PHPDocs elsewhere, but usually if Intelisense cannot tell what it is precisely, it would showmixed
– your is more precise, so check why. But that is for linter only and makes no difference at runtime. Also, if it isnull
by default typehinting asobject
would be incorrect. It’s?object
then.As for accessing
$args["post"]
– there’s no fancy magic you can pull – you either check for null prior calling, or use?->
syntax to not call on null (if you use PHP that supports that).I’m not sure what the support is like in Intelephense but you could try using array shapes which are widely supported by tools like Psalm, PHPStan, Phan and PhpStorm.
Example:
More info here: https://phpstan.org/writing-php-code/phpdoc-types#array-shapes