typescriptで配列のタイプを確認してください

sanderd17

TypescriptはどうやらASTで非常にうまく機能しているようです。をチェックするx.type == "Abc"と、次の行、typescriptxはタイプがであることわかりAbcます。これを使用して、JSDOC形式の型注釈付きのJSファイルを型チェックすることに注意してください。しかし、私は同じことが純粋なタイプスクリプトファイルにも当てはまると思います

ただし、要素の配列のテストに問題があります。

この最初の例は機能します。これは、すべての要素をループし、型がチェックされている場合にのみプッシュするためです。だから、typescriptです正しくタイプを推定Property[]機能の戻り値の型として

/**
 * @param {ObjectExpression} objectAst
 */
function getPropertiesList(objectAst) {
    let propertiesList = []
    for (let p of objectAst.value.properties) {
        if (p.type == "Property")
            propertiesList.push(p)
        else
            throw new Error("Properties field has elements that aren't of type `Property`")
    }
    return propertiesList
}

ただし、この例は機能的には同じです(ただし、私の目にはよりクリーンで、新しい配列を作成しません)は機能しません。推測されるタイプは(SpreadElement|Property|ObjectMethod|ObjectProperty|SpreadProperty)[]です。したがって、チェックは考慮されません。

/**
 * @param {ObjectExpression} objectAst
 */
function getPropertiesList(objectAst) {
    let propertiesList = objectAst.value.properties
    if (!propertiesList.every(p => p.type == "Property"))
        throw new Error("Properties field has elements that aren't of type `Property`")
    return propertiesList
}

typescriptが1つのケースを他のケースとどのように異なる方法で処理するかについて誰かが洞察を与えることができますか?

Typescriptは、チェックを使用して特定のタイプをより具体的にすることができます(最初の例が機能するため)が、配列に対してそれらのチェックを実行できないようです。

これはtypescriptコンパイラのバグと見なすことができますか(両方のコードが明らかに同じ型を返すはずなので)?

編集:コンテキストとテスト容易性を与えるためにrecast、次のようにタイプをインポートしました

/**
 * @typedef { import('recast').types.namedTypes.ObjectExpression} ObjectExpression 
 * @typedef { import('recast').types.namedTypes.Property} Property 
*/
jcalz

問題は、コンパイラがarray.every()、の型の型ガードとして使用できることを理解していないことですarrayさらに、コールバック関数p => p.type == "Property"は、の型の型ガードであるとは推測されませんpコンパイラーは、潜在的な型の絞り込みについてインラインコードを分析するのに非常に優れていますが、制御フローが関数に渡されると、ほとんど諦めます(microsoft / TypeScript#9998を参照)

TypeScriptに、boolean戻り関数の呼び出しが型ガードとして機能することを理解させたい場合はユーザー定義の型ガードなどの関数に手動で注釈を付ける必要があります以下のような機能がfoo(x: T): booleanに変更することができfoo(x: T): x is U、「どこx is U"型述語場合。foo(val)リターンはtrue、コンパイラが狭くなりますvalU。そうでなければ、それはしません。

コールバックの場合、これをに変更p => p.type == "Property"する必要があります(p): p is Property => type == "Property"の場合array.every()、そのメソッドはインターフェイス内の標準ライブラリで宣言されてArray<T>ます。幸い、追加のメソッドオーバーロードをインターフェイスマージできます(コードがモジュール内にある場合は、グローバル拡張使用してのようなグローバルインターフェイスに追加する必要がある場合があることに注意してくださいArray<T>)。次のようになります。

interface Array<T> {
    every<U extends T>(cb: (x: T) => x is U): this is Array<U>;
}

これで、コンパイラは、コールバックがタイプガード関数である場合、それevery()自体がタイプガードとして機能することを確認しますそして、あなたのコードは望み通りに機能します:

function getPropertiesList(objectAst: ObjectAST): Property[] {
    let propertiesList = objectAst.value.properties
    if (!propertiesList.every((p): p is Property => p.type == "Property"))
        throw new Error("Properties field has elements that aren't of type `Property`")
    return propertiesList
}

every()ただし、これは1回の使用には多すぎる作業になる可能性があります。実際には、おそらくタイプアサーション使用して先に進む必要があります。型アサーションは、コンパイラーよりも型についてよく知っている状況を対象としています。これは、次のいずれかを使用するのに妥当な時期です。

function getPropertiesListAssert(objectAst: ObjectAST): Property[] {
    let propertiesList = objectAst.value.properties
    if (!propertiesList.every(p => p.type == "Property"))
        throw new Error("Properties field has elements that aren't of type `Property`")
    return propertiesList as Property[]; // assert
}

さて、それが役立つことを願っています。幸運を!

コードへの遊び場リンク

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

numpy配列内のタイプを確認してください

分類Dev

KotlinでArrayListのタイプを確認してください

分類Dev

「this」の要素のタイプを確認してください

分類Dev

変数のタイプを確認してください

分類Dev

Typescript:文字列の数値を確認してください

分類Dev

配列内の値を確認してくださいFlutter dart

分類Dev

配列のソートを確認してください

分類Dev

配列の同じ値を確認してください

分類Dev

値が0の配列を確認してください

分類Dev

PHPの配列要素を確認してください

分類Dev

配列のサブ要素を確認してください

分類Dev

最後の配列要素を確認してください

分類Dev

配列が空のC ++を確認してください

分類Dev

numpy配列の形状を確認してください

分類Dev

配列phpで同様のテキストを確認してください

分類Dev

Pythonで配列要素の最大長を確認してください

分類Dev

jsonの2つの配列のサイズが同じであることを確認してください

分類Dev

ループ内で、配列にJavascript / QMLの次の要素があることを確認してください

分類Dev

列タイプifステートメントを確認してください

分類Dev

TypeScript:タイプ 'Message' | 'Message []'の約束ですが、タイプが 'Message'であることを確認してください

分類Dev

任意のタイプの配列に要素が含まれているかどうかを確認してください

分類Dev

Xtendバリデーターのタイプを確認してください

分類Dev

完全なタイプを確認してください

分類Dev

Ansible-変数タイプを確認してください

分類Dev

ジェネリックのタイプを確認してください

分類Dev

アカウントのタイプを確認してください

分類Dev

応答のパラメータで2つのタイプを確認してください

分類Dev

配列内の要素が配列であるかどうかをjavascript / jqueryで確認してください

分類Dev

列挙型TypeScriptで文字列値を確認してください

Related 関連記事

  1. 1

    numpy配列内のタイプを確認してください

  2. 2

    KotlinでArrayListのタイプを確認してください

  3. 3

    「this」の要素のタイプを確認してください

  4. 4

    変数のタイプを確認してください

  5. 5

    Typescript:文字列の数値を確認してください

  6. 6

    配列内の値を確認してくださいFlutter dart

  7. 7

    配列のソートを確認してください

  8. 8

    配列の同じ値を確認してください

  9. 9

    値が0の配列を確認してください

  10. 10

    PHPの配列要素を確認してください

  11. 11

    配列のサブ要素を確認してください

  12. 12

    最後の配列要素を確認してください

  13. 13

    配列が空のC ++を確認してください

  14. 14

    numpy配列の形状を確認してください

  15. 15

    配列phpで同様のテキストを確認してください

  16. 16

    Pythonで配列要素の最大長を確認してください

  17. 17

    jsonの2つの配列のサイズが同じであることを確認してください

  18. 18

    ループ内で、配列にJavascript / QMLの次の要素があることを確認してください

  19. 19

    列タイプifステートメントを確認してください

  20. 20

    TypeScript:タイプ 'Message' | 'Message []'の約束ですが、タイプが 'Message'であることを確認してください

  21. 21

    任意のタイプの配列に要素が含まれているかどうかを確認してください

  22. 22

    Xtendバリデーターのタイプを確認してください

  23. 23

    完全なタイプを確認してください

  24. 24

    Ansible-変数タイプを確認してください

  25. 25

    ジェネリックのタイプを確認してください

  26. 26

    アカウントのタイプを確認してください

  27. 27

    応答のパラメータで2つのタイプを確認してください

  28. 28

    配列内の要素が配列であるかどうかをjavascript / jqueryで確認してください

  29. 29

    列挙型TypeScriptで文字列値を確認してください

ホットタグ

アーカイブ