web-dev-qa-db-ja.com

TypeScriptインターフェイスでプロパティオブジェクトを説明する

入れ子になったオブジェクトとのインターフェイスについて説明したいと思います。ネストされたオブジェクトのインターフェイスを作成せずにそれを行うにはどうすればよいですか?

interface ISome {
  strProp:string;
  complexProp:{
    someStrKeyWhichIsDynamic:{
      value:string;
      optValue?:string;
    }
  };
}

私も試しました(PD:実際は大丈夫です

interface ISome {
  strProp:string;
  complexProp:{
    [someStrKeyWhichIsDynamic:string]:{
      value:string;
      optValue?:string;
    }
  };
}

しかし、私はのようなオブジェクトを割り当てることはできません

let dynamicStrKey = 'myKey';
  {
   strProp:'str', 
   complexProp:{
     [dynamicStrKey]:{
       value:'something here',
       optValue: 'ok, that too',
    }
  };

型アサーションなしのISome型の変数へ<ISome>。少なくともWebStormはこの割り当てをエラーとして強調表示します。

ネストされたオブジェクトを適切に説明するにはどうすればよいですか?

7
Alendorff

最後に、2番目のバリアントは正しかったと思います

interface ISome {
  strProp:string;
  complexProp:{
    [someStrKeyWhichIsDynamic:string]:{
      value:string;
      optValue?:string;
    }
  };
}

動的キーの場合は、[dynamic:string]ここに文字列プロパティがあることを指定します。問題に関係のないウェブストームエラーが発生したようです。

ところで、いくつかの文字列ベースの列挙型がある場合は、[key in MyEnum]: {...} の代わりに [key:string]。それはエラーを解決します:

TS1337インデックスシグネチャパラメータタイプは、共用体タイプであってはなりません。

そしてあなたがリテラルオブジェクトを持っている場合、例えばconst obj = { prop1: 'blah', prop2: 'blahblah' }

[key in keyof typeof obj]: {...}は、動的キーは 'prop1'または 'prop2'(またはより一般的にはObject.keys(obj))

5
Alendorff

最初の2つの例に問題はありません。彼らは両方ともうまくコンパイルし、彼らが言うことを意味します。

3番目の例では、プロパティ名を「動的」にしたいようです。ただし、TSはコンパイル時に動作します。コンパイル時には、dynamicStrKeyにはまだ値がありません。したがって、型定義でプロパティ名として使用しても意味がありません。ランタイム値を使用してコンパイル時アーティファクトを定義することはできません。

3
user663031

2番目の部分のコードは動的プロパティをサポートします。最後のタイプでは使用できません。型がJavaScriptコードに出力されないためです。代わりにジェネリックを使用して、以下のように思います。詳細については、TypeScriptを参照してください インデックスタイプ

interface ISome<K extends string> {
    strProp: string;
    complexProp: {
        [P in K]: {
            value: string;
            optValue?: string;
        }
    };
}


let foo: ISome<"foo"> = {
    strProp:"foo",
    complexProp:{
        foo:{
            value:"foo"
        }
    }
};

let bar: ISome<"bar"> = {
    strProp:"bar",
    complexProp:{
        bar:{
            value:"bar",
            optValue:"<optional>"
        }
    }
};

let foobar: ISome<"foo"|"bar"> = {
    strProp:"foo",
    complexProp:{
        foo:{
            value:"foo"
        },
        bar:{
            value:"bar",
            optValue:"<optional>"
        }
    }
};

// interesting things that use with any|never types
let anything:ISome<any|never>={
    strProp:"foo",
    complexProp:{}
};
2
holi-java