PhpStorm:有没有办法使用内联 PHPDoc 注释在 return 语句上强制执行类型?

问题描述

考虑以下代码:

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Car extends Model
{
    public static function getTheFirstCar(string $color): ?self
    {
        /** @var ?self */ // <-- Doesn't apply! Is there any alternative?
        return (new self())->newQuery()->firstWhere('color','=',$color);
    }
}

代码运行正常;尽管如此 PhpStorm 抱怨:

返回值应为“Car|null”,
\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model”返回

PhpStorm PHPDoc Type Annotation on return statement

将表达式的结果分配给带注释的变量可以解决警告,但会引入一个“冗余” 变量!

/** @var ?self $redundant */
$redundant = (new self())->newQuery()->firstWhere('color',$color);
return $redundant;

那么,PhpStorm 中是否有一种方法可以将 return 语句表达式的值强制执行内联类型注释,显式为 Car|null,而不引入冗余变量或指定所有预期返回类型?

解决方法

您可以通过在语句前添加 @noinspection PhpIncompatibleReturnTypeInspection 注释来取消此警告。
我个人不会这样做,但这是您关于如何“强制”返回类型并抑制警告 afaik 问题的唯一答案。

    /** @noinspection PhpIncompatibleReturnTypeInspection */
    return (new self())->newQuery()->where('color','=',$color)->first();

如果您决定尊重警告,那么这可能是它的原因和解决方案: newQuery() 将在模型表上创建一个新查询(最有可能是:cars)而不设置适当的模型 (Car)。
在内部,您现在正在对 cars 运行一个裸查询。因此,您将收到适当的记录,但不会是 Car 的实例,而是 Model 的实例。因此,PhpStorm 期望此处有多个额外的返回类型,并在您的语句中打印此警告,因为它与方法返回类型 ?self 不同。

快速解决方案是将 newQuery() 更改为 newModelQuery()。这将创建一个新查询并在创建的查询上设置模型 Car 并返回适当的实例或 null

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Car extends Model
{
    public static function getTheFirstCar(string $color): ?self
    {
        return (new self())->newModelQuery()->firstWhere('color',$color);
        // I'd use this statement though:
        // return self::where('color',$color)->first();
    }
}
,

你需要在你的类中添加文档块:

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
/**
 * Class Car
 * @package App\Models
 *
 * @method self|Builder newQuery()
 * @method ?self firstWhere($column,$operator = null,$value = null,$boolean = 'and')
 */
class Car extends Model
{
    public static function getTheFirstCar(string $color): ?self
    {
        return (new self())->newQuery()->firstWhere('color',$color);
    }
}

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...