

下記のコードで、オブジェクトは 'undefined' である可能性があります。ts(2532)  
と、test[i].vの部分でエラーになってしまうのですが、原因がさっぱりわかりません。  
コードの書き方で回避する方法はありますでしょうか？

[code]

    // test.ts
    type TestArray = {
      v: string;
    }
    let test: TestArray[] = [];
    for (let i = 0; i < test.length; i++) {
      if (test[i] && "1.1" == test[i].v) {
        console.log(test);
      }
    }
    
[/code]


CC BY-SA 4.0
2022-10-04T01:12:28.250
91438
2022-10-04T04:13:40.810
2022-10-04T04:11:39.680
3054
54688
question
typescript
TypeScriptでインデックスアクセス時のundefinedを回避したい


（`tsconfig.json` などで `"noUncheckedIndexedAccess": true`
としていることを前提とします。そうでなければ、質問のエラーは出ないことでしょう）

[型の絞り込み
(Narrowing)](https://www.typescriptlang.org/docs/handbook/2/narrowing.html)
が行なわれる対象は変数です。`test[i]` のような式の型は絞り込めません。

### 変数に代入する

よって、変数に代入してから扱うことが考えられます。

[code]

    for (let i = 0; i < test.length; i++) {
        // ここで代入
        const val = test[i]
    
        // 左でチェックしたので、右の val は 非undefined に絞り込まれる
        if (val && "1.1" == val.v) {
            console.log(val)
        }
    }
    
[/code]

### オプショナルチェーン

[オプショナルチェーン](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Optional_chaining)
を使うとチェックがコンパクトに書け、TypeScript の型も問題ないです。

[code]

    for (let i = 0; i < test.length; i++) {
        // `test[i]?.v` の結果は undefined かも知れませんが、
        // この場合、"1.1" との比較で false になるので問題無いです。
        if ("1.1" == test[i]?.v) {
            console.log(test[i])
        }
    }
    
[/code]

### 非 null アサーション演算子 (`!`)

`undefined` では無いことが確実であるならば、[非 null アサーション演算子 (Non-Null Assertion
Operator)](https://www.typescriptlang.org/docs/handbook/2/everyday-
types.html#non-null-assertion-operator-postfix-) を使ってチェックを省略できます。

（自作のコードの場合は大丈夫でしょうが、JavaScript
の世界ではプロパティーを読むだけで内容が変わるオブジェクトも存在しますので、コードのこの部分だけ見ても、確実なことは言えません）

[code]

    for (let i = 0; i < test.length; i++) {
        // test[i] は undefined では無いことを知っているので、
        // TypeScript に伝える。間違っていたら ランタイムエラー。
        if ("1.1" == test[i]!.v) {
            console.log(test[i])
        }
    }
    
[/code]

### 別のループ方法

構文によっては自分でチェックする必要が無いです。

[code]

    // 「for of」ループ
    for (const val of test) {
        if ("1.1" == val.v) {
            console.log(val)
        }
    }
    
    // forEach
    test.forEach((val) => {
        if ("1.1" == val.v) {
            console.log(val)
        }
    })
    
[/code]


CC BY-SA 4.0
2022-10-04T04:06:23.953
91440
2022-10-04T04:13:40.810
2022-10-04T04:13:40.810
3054
3054
91438
answer