TypeScriptインターフェイスプロパティのタイプを「抽出」する方法はありますか?


123

いくつかのインターフェースを含むライブラリXのタイピングファイルがあるとしましょう。

interface I1 {
    x: any;
}

interface I2 {
    y: {
        a: I1,
        b: I1,
        c: I1
    }
    z: any
}

このライブラリを操作するには、とまったく同じタイプのオブジェクトを渡す必要がありますI2.y。もちろん、ソースファイルに同じインターフェイスを作成できます。

interface MyInterface {
    a: I1,
    b: I1,
    c: I1
}

let myVar: MyInterface;

しかし、ライブラリからのものを最新の状態に保つという負担がかかります。さらに、それは非常に大きくなり、多くのコードの重複が発生する可能性があります。

したがって、インターフェイスのこの特定のプロパティのタイプを「抽出」する方法はありますか?似たようなものlet myVar: typeof I2.y(これは機能せず、「名前I2が見つかりません」エラーが発生します)。前もって感謝します。


編集:TS Playgroundで少し遊んだ後、次のコードが私が望んでいることを正確に達成していることに気づきました:

declare var x: I2;
let y: typeof x.y;

ただし、冗長変数xを宣言する必要があります。私はその宣言なしでこれを達成する方法を探しています。


1
これは機能しません-それはどのように現れますか?表示される実際のエラーメッセージは何ですか?
Bartek Banachewicz 2016年

@BartekBanachewicz更新
Kuba

回答:


249

以前は不可能でしたが、TypeScriptバージョン2.1以降、幸いなことに現在は可能です。2016年12月7日にリリースされ、ルックアップタイプとも呼ばれるインデックス付きアクセスタイプが導入されています

構文は要素アクセスとまったく同じように見えますが、型の代わりに記述されています。だからあなたの場合:

interface I1 {
    x: any;
}

interface I2 {
    y: {
        a: I1,
        b: I1,
        c: I1
    }
    z: any
}

let myVar: I2['y'];  // indexed access type

現在のmyVarタイプはI2.y

TypeScriptPlaygroundで確認してください。


1
'y'が配列の場合、要素の型を抽出する方法はありますか?例えばI2 {Y:{..} []}
ジョンB

1
@JohnBはい、配列インデックスはオブジェクトプロパティとまったく同じであるため、まったく同じ方法で実行できます。ここでそれをチェックアウト:typescriptlang.org/play/...
クバJagoda

3
@JohnBはい、同じ方法でアクセスできます。I2['y'][0]参照:typescriptlang.org/play/...
のMichałMiszczyszyn

2
これは本当にすごいことです
Geradlus_RU

1
I2タイプとしてを使用して定義されたオブジェクトのキーをループしていると仮定しましょう。ループするときに特定のキーのタイプを動的に取得するにはどうすればよいですか。この; let z: typeof x[a];aは文字列としての特定のキーですが、機能しません。a値を参照し、タイプを参照する必要があることを教えてくれます。どうすればこれを行うことができますか?どうにかしてそれも可能ですか?THX!
エミールヴァルザー

-2

インターフェイスは、オブジェクトの定義のようなものです。その場合、yはI2オブジェクトのプロパティであり、特定のタイプであり、その場合は「匿名」です。

別のインターフェースを使用してyを定義し、それを次のようにyタイプとして使用できます。

interface ytype {
   a: I1;
   b: I1;
   c: I1;
}

interface I2 {
    y: ytype;
    z: any;
}

インターフェイスをファイルに入れてextractを使用すると、プロジェクトの他のファイルにインポートできます。

export interface ytype {
   a: I1;
   b: I1;
   c: I1;
}



 export interface I2 {
        y: ytype;
        z: any;
    }

あなたはそれをそのようにインポートすることができます:

   import {I1, I2, ytype} from 'your_file'

すべて問題ありませんが、前述したように、インターフェイスI1とI2は外部ライブラリから取得され、そのライブラリのd.tsファイルで定義されています。したがって、このytypeインターフェースを持つことはコードの重複であり、絶えず更新する必要があります。
クバジャゴダ2016年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.