在可选流类型上安全访问属性

时间:2018-04-26 16:27:17

标签: javascript flowtype

我想安全地访问由外部库(mobx)设置的Union Type(所有选项都是接口)上的属性。

 Cannot call observe because:
 Either property added is missing in IArrayChange [1] but exists in IArraySplice [2] in the first argument.
 Or property added is missing in IObjectChange [3] but exists in IArraySplice [2] in the first argument.

 142│     observe(thisContainer.items, (change: IArraySplice<any>) => {
 143│        change.added.forEach((item: Item) => this.observeChanges(item));
 145│     });
 146│   }
 147│

 node_modules/mobx/lib/mobx.js.flow
  356│     listener: (change: IArrayChange<T> | IArraySplice<T>) => void,

  372│     listener: (change: IObjectChange) => void,

我试过了:

  • 在运行change.added.iterator之前使用条件检查.added是否存在。 if (change.added){&amp;&amp; if ('added' in change) {

  • 使用条件检查通用属性type是否设置为splice。这应该确保添加的属性也可用。 change.type === 'splice' && change.added...

文档建议典型的是为类型检查编写条件 https://flow.org/en/docs/types/unions/ 但我不确定使用外部库接口的最佳方法。像Interface type check with Typescript这样的创作功能比我满足规则预提交类型检查器的感觉更重。

应该怎么做?

1 个答案:

答案 0 :(得分:0)

工作解决方案:

observe(thisContainer.items, (change: IArraySplice<any> | IArraySplice<T>) => {
    if (change.type === 'splice') {
        change.added.forEach((item: Item) => this.observeChanges(item));
    }
});

<强>解释

虽然错误消息侧重于属性的存在,但是错误是在b / c时触发的,传递的参数不一定是预期的。

由于mobx IObservableArray更改可以生成IArraySplice<T>IArraySplice<T>,因此Flow类型需要考虑。

一旦处理完毕,预期的两个属性都可用于细化。

供参考,实施mobx类型:

export interface IArrayChange<T> {
    type: "update",
    object: IObservableArray<T>,
    index: number,
    newValue: T,
    oldValue: T
}

export interface IArraySplice<T> {
    type: "splice",
    object: IObservableArray<T>,
    index: number,
    added: T[],
    addedCount: number,
    removed: T[],
    removedCount: number
}