1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

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

Last updated at Posted at 2022-05-27

やりたいこと

"no value type specified in iterable type array"を解消したい

エラー内容・原因

エラーの原因は2つ

  • getInputs関数の引数の$inputsの配列の構成要素が明示されていない
  • 戻り値の配列の構成要素が明示されていない

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

コード

//$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]]
結果
  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>>とする必要はない

修正後のコード
/**
 *
 * @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]]
結果
 1/1 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
                                                                                                                       
 [OK] No errors   

補足(1) ~@pramなど~

@paramは、引数に使う
@returnは、戻り値に使う
@varは、変数に使う

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

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

補足(2)mixedを使う

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

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

安易に['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.

typehint = 型宣言

補足(3)配列の中のインスタンスを明示したい(object[]を使おう)

前提として、$cardsプロパティの配列にCardインスタンスが沢山入ってます。[Card(ハート,A),Card(ハート,2)....]

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

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

オブジェクト型
    /**
     * @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);
            }
        }
    }

参考記事

まとめ

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

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?