次のコードがあるとします:
/* @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
をプルしているときに、インターフェイスIDefaultSettings
でkey
のインデクサープロップが必要なのはなぜですか。 key
は?両方のオブジェクトdefaultSettings
&settings
は、同じタイプ/構造IDefaultSettings
です。
助けてください&ありがとう!
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;
}
}
}
( 試す )