3

我有以下代码:

$request->headers->get('Accept-Language', 'en');

我提供了一个默认值,但 Psalm 认为它可能为 null,因为->get()声明返回一个可为空的字符串:

// vendor/symfony/http-foundation/HeaderBag.php
/**
 * Returns a header value by name.
 *
 * @return string|null The first header value or default value
 */
public function get(string $key, string $default = null) { /* */ }

我该如何解决这个问题,所以 psalm 知道它不为空?

4

2 回答 2

1

由于您无法控制上游库中的注释,因此您必须在自己的代码中向 Psalm 提供缺失的信息。

有几种方法可以解决它:

转换成字符串,所以 Psalm 毫无疑问get()会得到什么类型:

$a = (string) $request->headers->get('Accept-Language', 'en');

是的,演员阵容是多余的,但清晰简洁。我通常这样做只是为了经济。

您可以显式声明此get()调用结果的变量是一个字符串:

/** @var string $acceptLanguage **/
$acceptLanguage = $request->headers->get('Accept-Language', 'en');

最后,你可以简单地抑制PossiblyNullArgument你需要的地方:

/** @psalm-suppress PossiblyNullArgument */
iWantAString($request->headers->get('Accept-Language', 'en'));

在这里查看所有这些工作。

您还可以将上述一些方法与您自己的包装器方法结合起来,以处理从请求中获取值,确保始终返回字符串。throw如果你这样做,如果找不到参数,你可能应该是一个异常。

于 2020-11-23T10:04:42.020 回答
0

除了 @yivi 的回答向您展示如何覆盖类型推断或抑制错误之外,您还可以通过直接在源代码中使用条件类型提供正确的 docblock 来向 Psalm解释类型(如果您可以控制它)或在存根文件中。

/**
 * Returns a header value by name.
 *
 * @psalm-return ($default is null ? (string|null) : string)
 */
public function get(string $key, string $default = null) { /* */ }

https://psalm.dev/r/41b8471847

于 2021-03-20T22:42:50.767 回答