PHPStan 转换为更具体的数组形状

问题描述 投票:0回答:1

在我的代码中,我调用一个方法,其返回值的类型如下:

/**
 * @return array<int, array<string,mixed>>
 */
public function fetchAllAssociative(): array;

子类型

array<string, mixed>
以通用方式描述数据库记录。我确切地知道这个数据库记录是什么样子,所以我想更具体地记录该方法:

/**
 * @return array<int, array{id: int, firstName: string, lastName: string}>
 */
public function getAllUsers(): array
{
  return $this->userRepository->fetchAllAssociative();
}

然而,PHPStan 抱怨说我应该完全按照

fetchAllAssociative
:

输入我的方法

Method UserRepository::getAllUsers() should return array<int, array{id: int, firstName: string, lastName: string}> but returns array<int, array<string, mixed>>.

有办法投射吗?我的解决方法是引入一个新变量并使用

@var
标签,但我不太喜欢它(其他静态代码分析工具也不喜欢它)

/**
 * @return array<int, array{id: int, firstName: string, lastName: string}>
 */
public function getAllUsers(): array
{
  /**
   * @var array<int, array{id: int, firstName: string, lastName: string}> $data
   */
  $data = $this->userRepository->fetchAllAssociative();

  return $data;
}
phpstan array-shape
1个回答
0
投票

我遇到了类似的事情。不幸的是,我认为在实现中添加

// @phpstan-ignore-next-line
是您唯一可以做的事情。

在 Typescript 中,这基本上相当于断言

any
User
。通常,当您获取并验证数据(例如来自数据库或 http 请求)时,这会在“makeUser”函数中发生,以便您可以最大限度地减少
data as unknown as User
的使用。不然就是这个后果。

因此,一般建议其他遇到此问题的人,从您的存储库开始,真正避免

array<mixed>
mixed
,因为它会很快渗透到您的系统中。

© www.soinside.com 2019 - 2024. All rights reserved.