为什么不流动理解我的分支回报值

时间:2017-06-22 12:58:33

标签: flowtype

我们来看这个例子:

type Obj = {
  number: number,
  string: string,
}

const obj: Obj = {
    number: 1,
    string: "test",
};

type Key = $Keys<Obj>;

const getValue = (key: Key) => {
    return obj[key];
};

const myString = getValue('string');

这将返回myStringstring | number

由于Flow知道我的'string'是可能的key之一,所以它允许我从obj获取它。为什么它不知道这只能返回一个字符串类型?

2 个答案:

答案 0 :(得分:1)

直到最近,在Flow中做到这一点是不可能的,但是你很幸运!最新的0.49版本附带了一个$ ElementType实用程序类型,可以解决这个问题。

这是flow.org/try链接。

在此处发布示例以防链接中断:

const obj = {
  number: 1,
  string: "test"
}

function getValue<Key: string>(key: Key): $ElementType<typeof obj, Key> {
  return obj[key];
}

const x: number = getValue('number')
const y: string = getValue('string')

// errors below
// const a: string = getValue('number')
// const b: number = getValue('string')

我清理了你的例子 - 没有必要创建&#39; Obj&#39;类型,你可以使用typeof。希望这有帮助!

请注意,如果您尝试使用$Keys<typeof obj>作为getValue的泛型参数的边界,则$ ElementType目前会出错。这个问题正在跟踪:https://github.com/facebook/flow/issues/4211

答案 1 :(得分:0)

因为流量仅在功能边界静态计算您的类型而将无法运行您的代码。

这是一个简化的例子:

function foo(x: 'a' | 'b') {
  if (x === 'a') {
    return 'a';
  }
  return 'b';
}

你可能认为我们可以写:

const surprise: 'a' = foo('a');

这是一个错误,因为foo的返回类型是'a'| 'B'