web-dev-qa-db-ja.com

Flowtype:インデクサープロパティがありません

次のコードがあるとします:

/* @flow */
interface IDefaultSettings {
  Drivers?: {},
  Options?: {}
}

const defaultSettings: IDefaultSettings = {
  Drivers: {},
  Options: {}
}

const settings: IDefaultSettings = {};

mergeSettings(settings);

function mergeSettings(settings: IDefaultSettings) {
  for (const [key, setting] of Object.entries(defaultSettings)) {
    switch(key) {
      case 'Drivers':
      case 'Options':
        settings[key] = setting;
        break;
    }
  }
}

上記のコードを Flow playgound に配置して、これを試してください。

この糸くずのエラーが発生し、解決できません:"Cannot assign `setting` to `settings[key]` because an indexer property is missing in `IDefaultSettings` [1]."

このコードが既知のインターフェイスを持つオブジェクトからkeyをプルしているときに、インターフェイスIDefaultSettingskeyのインデクサープロップが必要なのはなぜですか。 keyは?両方のオブジェクトdefaultSettingssettingsは、同じタイプ/構造IDefaultSettingsです。

助けてください&ありがとう!

6
darkkenergy

interfaceではなくtypeを使用した理由はわかりませんが、問題の具体的な理由はわかりません。これは、フローが有効なプロパティ名を判断できないことを意味します。フローはこれではあまりよくありませんが、静的型チェッカーであるため、変数内のすべてを包括的に比較することはできません。

typeに切り替えると、indexer propertyエラーは解消されますが、新しいエラーが導入されます。つまり、Object.entriesからの戻り値の型は、値がmixed型のタプルです。

IDefaultSettingsにはオブジェクト値を持つ2つのキーがあるので、フローはそれらが別の何かである可能性があるという考えに頭を悩ませています。少しハックですが、解決策はanyを介して値をキャストすることです。または、$FlowFixMeコメント構文を使用して、エラーをミュートする理由を文書化します。

type IDefaultSettings = {
  Drivers?: {},
  Options?: {}
}

const defaultSettings: IDefaultSettings = {
  Drivers: {},
  Options: {}
}

const settings: IDefaultSettings = {};

mergeSettings(settings);

function mergeSettings(settings: IDefaultSettings) {
  for (const [key, setting] of Object.entries(defaultSettings)) {
    switch(key) {
      case 'Drivers':
      case 'Options':
        settings[key] = (setting: any);
        break;
    }
  }
}

試す

5
Dave Meehan