Ecmascript 6 流:在映射/过滤/减少期间保留类型

Ecmascript 6 流:在映射/过滤/减少期间保留类型,ecmascript-6,flowtype,Ecmascript 6,Flowtype,如何在正确推断键类型的同时过滤/减少类型化对象?例如: /* @flow */ type A = { a0?: string, a1?: boolean, a2?: number } type B = { b0?: string, b1?: boolean, b2?: number } type AB = A & B const keysA = ['a0', 'a1', 'a2'] // Given an AB object, keep only the ke

如何在正确推断键类型的同时过滤/减少类型化对象?例如:

/* @flow */
type A = {
  a0?: string,
  a1?: boolean,
  a2?: number
}
type B = {
  b0?: string,
  b1?: boolean,
  b2?: number
}
type AB = A & B

const keysA = ['a0', 'a1', 'a2']

// Given an AB object, keep only the keys that belong in type A
function keepA(ab: AB):A {
  return keysA
    .filter(prop => ab.hasOwnProperty(prop))
    .reduce((obj, prop) => {
      obj[prop] = ab[prop]
      return obj
    }, {} )
}

function flowTest(ab: AB) {
  const a = keepA(ab)
  return a
}
这会引发一个错误:

obj[prop] = ab[prop]                     
            ^ Cannot return `keysA.filter(...).reduce(...)` 
              because boolean [1] is incompatible with 
              string [2] in property `a0`.
References:
4:   a1?: boolean,
          ^ [1]
3:   a0?: string,
          ^ [2]
在赋值
obj[prop]=ab[prop]
中,flow认为右边可以是
string | boolean | number
中的任意一个

这里是flow.org/try:


我对Flow(以及一般的类型检查)非常陌生。

.filter(prop=>ab[prop])
可能不是你想说的。您给
过滤器
的闭包应该返回
布尔值
,但这将返回
字符串
布尔值
数字
,取决于您访问的属性。Flow将无法推断
keysA
数组中的值正是
A
中的字段名。即使可以,其他一些代码也可以修改
keysA
数组,然后它会中断-流静态运行,不知道是否会发生这种情况。@PeterHall感谢您指出筛选器错误。这太愚蠢了,我把它改成了
ab.hasOwnProperty(prop)
。关于“Flow将无法推断…”,您能否建议一种合理的方法来重构Flow能够理解的内容?类似于:@PeterHall,它将
ab
的可选属性作为
keepA(ab)
(值
未定义
)的属性。A
for…in
循环
ab
似乎有效: