【PHPStan】 "no value type specified in iterable type array"の解決方法

やりたいこと
---------------
"no value type specified in iterable type array"を解消したい


エラー内容・原因
---------------
エラーの原因は２つ
* getInputs関数の引数の$inputsの配列の構成要素が明示されていない
* 戻り値の配列の構成要素が明示されていない

:::note warn
引数と戻り値のどちらにもarray型の指定はされているが、配列内のキーと要素の型まで指定されていないことが原因
:::

```php:コード

//$inputsの配列の要素は具体的にどうなってる？
//戻り値の配列の要素は具体的にどうなってる？
//記載がないから分からない！
function getInputs(array $inputs): array
{
    $inputs = array_slice($inputs, 1);
    return array_chunk($inputs, 2);
}

$inputs = getInputs(['test', 10, 50, 80, 100]);

//結果
//['test', 10, 50, 80, 100]　 => [[10,50],[80,100]]
```
```phpstan:結果
  5      Function getInputs() has parameter $argv with no value type specified in iterable type array.  
         💡 See: https://phpstan.org/blog/solving-phpstan-no-value-type-specified-in-iterable-type    
  
  5      Function getInputs() return type has no value type specified in iterable type array.           
         💡 See: https://phpstan.org/blog/solving-phpstan-no-value-type-specified-in-iterable-type  

[ERROR] Found 2 errors    
```

解決策 `<キーの型,要素の型>`と明示する
---------------



* 引数の$inputsの要素は`['test', 10, 50, 80, 100]` => `array<int,string|int>`
キーは01234なのでint。値は文字列と数値の組み合わせなのでstring|intとなる

* 戻り値は2次元配列となっています。`[[10,50],[80,10]]` => `array<array<int,int>>`
_配列の要素が複数あっても`array<array<int,int>,array<int,int>>`とする必要はない_


```php:修正後のコード
/**
 *
 * @param  array<int,string|int> $inputs
 * @return array<array<int,int>>
 */

function getInputs(array $inputs): array
{
    $inputs = array_slice($inputs, 1);
    return array_chunk($inputs, 2);
}

$inputs = getInputs(['test', 10, 50, 80, 100]);
//結果
//['test', 10, 50, 80, 100]　 => [[10,50],[80,100]]
```
```phpstan:結果
 1/1 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
                                                                                                                       
 [OK] No errors   
```
補足（１） ~@pramなど~
---------------
`@param`は、引数に使う
`@return`は、戻り値に使う
`@var`は、変数に使う

`@var`で変数$nameが文字列であることを明示してる

```php:var例
/**
 * @var string $name
 */
$name = 'John';

```
補足（２）mixedを使う
---------------
array型で配列の要素がstringだったりintだったりで型が可変する場合で、かつ"no value type specified in iterable type array"を避けたいときは以下を使用する。

arrayを`mixed[]`または`array<mixed>`に置き換える

:::note warn
安易に`['test', 10, 50, 80, 100]`  なので `array<int,mixed>`とはせず、初めから型が分かっている場合はちゃんと`array<int,string|int>`と明示する。
もし、['test', 10, 50, 80, 100]の中に（'test'）stringを取るのか分からない時はmixedを使ってOK
:::


>If you have an array typehint and just want to make this error go away while keeping the possibility of the array holding any type, replace array with mixed[] or array<mixed>.

typehint = 型宣言

補足（３）配列の中のインスタンスを明示したい（object[]を使おう）
---------------
前提として、$cardsプロパティの配列にCardインスタンスが沢山入ってます。`[Card(ハート,A),Card(ハート,2)....]`

ここでもプロパティの構成要素を明示する必要があります。
下記のように書くと、「$cardsプロパティはCardインスタンスをもつ配列ですよ〜」と明示できます。
`@var Card[]`

または、`@var object[]`とも書けます。

```php:オブジェクト型
    /**
     * @var Card[] $cards
     */

    private array $cards;

    public function __construct()
    {
        foreach (['ハート', 'クラブ', 'スペード', 'ダイヤ'] as $suite) {
            foreach (['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K'] as $number) {
                $this->cards[] = new Card($suite, $number);
            }
        }
    }
```

参考記事
---------------
https://phpstan.org/blog/solving-phpstan-no-value-type-specified-in-iterable-type

https://qiita.com/KEINOS/items/00139d2d9f9c11c6aa15

https://stackoverflow.com/questions/29165580/phpstorm-type-hinting-array-of-different-types

まとめ
---------------
phpmdでよく出るエラーですよね。。都度、構成要素も明示する方がプロパティや戻り値をど忘れせずにコードを書けそうで効率いいかもしれませんね！
そもそもプロパティ定義するたびに明示するのが当たり前なのかもですが笑