流程:使用地图

时间:2018-05-06 08:28:54

标签: javascript flowtype static-typing

我刚开始在我的一个项目中使用Facebook Flow实现类型检查,并遇到了一些问题。我正在尝试使用Map执行以下操作:

/* @flow */

let testMap: Map<string, Array<number>> = new Map();
let key: string = "testString";

if (!testMap.has(key)) {
  testMap.set(key, [])
}

testMap.get(key).push(1);

但我收到一个错误说:

Cannot call `testMap.get(...).push` because property `push` is missing in undefined [1]

尝试流程中的示例: https://flow.org/try/#0PQKgBAAgZgNg9gdzCYAoVMCmAXM3MDO2AsgIYAOAXGGeQDxEBOAlgHYDmANGAIKOOkAnnVYBXALYAjTIwB8ssAF4wrTEloAKAJQBuDDjABrTIOpM27JWABE+IgGVsLDtb2pmUMBoCEdkhQA6AAtSAg1jQS0tMABvVDA8Qn9yAIIccJNuAG0AXS1UAF90P1oA9nSIrQDyUQIgjQBGXVQgA

这当然是因为Map接口中的get函数定义为:

get(key: K): V | void;

但是我期待Flow能够识别出密钥实际上是在上面设置的。

有关如何更改代码以使Flow满意的任何建议?

非常感谢!

1 个答案:

答案 0 :(得分:3)

正如您所提到的,问题是,您Map.get的来电可能会返回void,如您在V | void中所见。

Flow无法知道您的密钥是否已定义,因为这可能会在运行时发生变化。

因此,在访问undefined方法之前,您需要检查返回的值是否不是push

const arr = testMap.get(key);

if (arr) {
  arr.push(1)
} else {
  // map "testMap" didn't contain a value for key "key"
}

流程代表中的完整演示:https://flow.org/try/#0PQKgBAAgZgNg9gdzCYAoVMCmAXM3MDO2AsgIYAOAXGGeQDxEBOAlgHYDmANGAIKOOkAnnVYBXALYAjTIwB8ssAF4wrTEloAKAJQBuDDjABrTIOpM27JWABE+IgGVsLDtb2pmUMBoCEdkhQA6AAtSAg1jQS0tMABvVDA8Qn9yAIIccJNuAG0AXS1UAF90AGM4ViIwUn4rP1oA9nSI3XQPLyrGaLiE9oDyUQIgjQBGfIKwTBg02PiwYGAwcQobWoprMAATZnXWAHJcUtZsUjZKsAA3UhhRTDAoOEYjExsI60KgA

另一种方法是这样的:

let arr = testMap.get(key);

if (!arr) {
  arr = [];
  testMap.set(key, arr);
}

arr.push(1);