2017-11-13 17 views
3

ネストされたプロパティに安全かつ簡単にアクセスする唯一の方法は、たった今_.getを使用するという問題がありました。例:安全なバージョンのlodash _.get - 配列型を条件付きで分解する

_.get(obj, "Some.Nested[2].Property", defaultValue); 

これは素晴らしいですが、頻繁に起こるようにプロパティの名前が変更されません。理論的には、次のように上記の変換と活字体が暗黙的に型チェックできるようにすることが可能であるべきである:

safeGet(obj, "Some", "Nested", 2, "Property", defaultValue); 

私は配列型を除くすべてのもののために、このようなタイピングを作成することに成功してきた:

function getSafe<TObject, P1 extends keyof TObject>(obj: TObject, p1: P1): TObject[P1]; 

function getSafe<TObject, P1 extends keyof TObject, P2 extends keyof TObject[P1]>(obj: TObject, p1: P1, p2: P2): TObject[P1][P2]; 

これは深度の項目を正しくチェックします(これらのステートメントは10レベルまで自動的に生成されます)。次のパラメータに渡される型がT[]であり、Tではないため、配列プロパティで失敗します。

解決策の複雑さや冗長性は、コードが自動生成されるため考慮されません。問題は、整数パラメータを受け取り、分解する型宣言の組み合わせを見つけることができないようです配列の型は前方に移動します。

T[number]を使用して配列を解体することができます(Tは配列です)。問題は、Tが入れ子になったプロパティの配列であるところを制約する方法がないことです。

実際に呼び出しサイトで働いて
function getSafe<TObject, P1 extends keyof TObject, P2 extends keyof TObject[P1][number]>(obj: TObject, p1: P1, index: number, p2: P2): TObject[P1][number][P2]; 
                       ^^^^^^                ^^^^^^ 
const test2 = getSafe(obj, "Employment", 0, "Id"); // example usage 

(そこにはエラーは、正しく私たちのparamを与え、戻り値の型)が、あなたは[number]とインデックスTObject[P1]我々はできるようにすることができないため、宣言自体に間違いを与えます保証TObject[P1]は配列です。

注:TType[number]が配列型から要素の型を取得するための実行可能な方法ですが、我々は、アレイにこれをやっているコンパイラを説得する必要があります)

質問が本当にあります、 TObject[P1]またはに配列制約を追加する方法があるのでしょうか?

答えて

2

私は以来、これを考え出したし、ここでNPMパッケージを公開した:ts-get-safe

キーポイントはどのように条件付き再構築、それの要素型に配列を考え出すました。これを行うには、まずすべてのプロパティが配列かneverであることを主張する必要があります。方程式を解くタイプだった:

type GSArrEl<TKeys extends keyof TObj, TObj> = { [P in TKeys]: undefined[] & TObj[P] }[TKeys][number]; 

魔法が{ [P in TKeys]: undefined[] & TObj[P] }ところ、我々は基本的に労働組合にundefined[]からTObjの各プロパティです。各プロパティは配列かnever(配列ではない各プロパティの上にneverとなる)のいずれかであることを確信しているので、要素タイプを取得するために構造式[number]を行うことができます。ここで

が同時に起こって構造化代入2つの配列の例である:配列やオブジェクトプロパティの組み合わせの

function getSafe<TObject, P0 extends keyof TObject, A1 extends GSArrEl<P0, TObject>, P2 extends keyof A1, P3 extends keyof A1[P2], A4 extends GSArrEl<P3, A1[P2]>>(obj: TObject, p0: P0, a1: number, p2: P2, p3: P3, a4: number): A4; 

何百もの私のts-get-safeライブラリに生成され、使用する準備ができているされている、しかし私は同じ宣言で動的な数のパラメータを使用できるように、これを一般的な方法で改善する方法はまだありません。同じタイプの制約に配列とプロパティのナビゲーションを組み合わせて、配列やプロパティへのアクセスのあらゆるバリエーションを生成する必要はありません。

関連する問題