流类型签名错误。为什么?

Error in flow type signature. Why?

例子如下:

https://flow.org/try/#0PQKgBAAgZgNg9gdzCYAoVUCuA7AxgFwEs5swBDMACgAcyAnMgWwGcAuMAb2oEZ3n86hbAHMANGGoAmAPx8BQ4QF8AlOwBucQgBNOi9FjxESYAEZVVnHnMEjFnVGDB0Apvkx1SXXmADk-G8I+igDcqHqoavSmAErOzJgw+GAAvKaUyqGoZJQmsfGJGUA

/* @flow */

function a (params: {p1: string, p2?: string}): void {}

function b (): {p1: string} {
  return {p1: 'string'};
} 

var bResult = b();

a(bResult);

我遇到了流程错误

3: function a (params: {p1: string, p2?: string}): void {}
                       ^ property `p2`. Property not found in
11: a(bResult);
      ^ object type

为什么会出现这个错误? 为什么签名 {p1: string} 不是 {p1: string, p2?: string} 的一部分?

类型{p1: string, p2?: string}意味着如果这个类型的值有p2属性,它必须是string。 Flow 的宽度子类型意味着 b 函数可以 return {p1: 'foo', p2: 6}。基本上,如果你有 {p1: string} 类型的东西,你知道它有 p1 属性 但你对它的其他属性一无所知。

因此,如果 Flow 允许您获取类型 {p1: string} 的内容并将其传递给需要类型 {p1: string, p2?: string}a 函数,则 a函数可以检查 p2 属性 是否存在,如果存在,它可以假设它是 string。但是,它实际上可能是 number ,如上所述。这会破坏类型安全。