这种流类型默认分配不应该给我一个错误吗?

Shouldn't this flow type default assignment give me an error?

我几乎没有学习流程,但根据文档,以下代码应该给我一个错误,因为我正在解构对象并将默认值分配给 'overrideKeyProp' 这不是布尔值.

没问题,没有错误:

type KeyGenCfgType = {|
  topic: Topic,
  keyProp?: string,
  overrideKeyProp?: boolean
|};

function cfgTypeKeyGen(kGen: KeyGenCfgType) {
  const { keyProp, overrideKeyProp = 1 } = kGen;
}

这给我一个关于 属性 overrideKeyProp:

上不匹配类型的错误
type KeyGenCfgType = {|
  topic: Topic,
  keyProp?: string,
  overrideKeyProp?: boolean
|};

function cfgTypeKeyGen({ keyProp, overrideKeyProp = 1 }: KeyGenCfgType) {
}

//number: This type is incompatible with boolean 

这也给我一个错误:

type KeyGenCfgType = {|
  topic: Topic,
  keyProp?: string,
  overrideKeyProp?: boolean
|};

function cfgTypeKeyGen(kGen: KeyGenCfgType) {
  const { keyProp, overrideKeyProp = 1, nope } = kGen;
}
// property `nope`: Property not found in object type    

所以它能够识别出我正在尝试解构一个不属于我为它定义的流类型的 属性,但它无法识别出我没有分配正确类型的属性 上的值,除非我在函数签名中进行解构。

关键是当您没有为给定变量声明为 Flow 指定类型时,它将推断类型。

function someFunc({ someProp = 1 }: SomeType) {}

明确地说“类型是具有这些属性的对象,使用 属性 的类型创建一个名为 someProp 的变量。在这种情况下分配一个数字显然是一个错误,因为你'已经明确说明 : SomeType.

的类型应该是什么
let { someProp = 1, unknownProp } = fnArg;

将失败,因为 Flow 确定 unknownProp 不是 fnArg 对象上可用的 属性。

所以对于你的问题,让我们看看你的例子

function someFunc(fnArg: SomeType) {
    let { someProp = 1 } = fnArg;
}
  • 您已经声明了函数输入类型,因此 Flow 知道对象上存在 someProp,并且 Flow 知道 fnArg.someProp 是什么类型。
  • 您已指定默认值 1

就是这样。你 not 告诉 Flow someProp 变量应该是什么类型。你可以做

let { someProp = 1 }: SomeType = fnArg;

这会引发您预期的错误。

Flow 正在做的是推断类型。因为它看到你在一部分中做 let someProp = fnArg.someProp,它可能是 string,但在代码的另一个分支中你正在做 let someProp = 1,所以它也可能是数字。您没有做任何事情来告诉 Flow someProp 必须是一个字符串。

您在通用代码中看到 Flow 中的类似行为:

let someVal;
if (Math.random()){
    someVal = "a string";
} else {
    someVal = 4;
}

这不是错误,Flow 推断 let someVal;let someVal: number|string;

如果您尝试 use the field for something

,您可以在类似您的代码中看到相同的内容
type SomeType = {
  prop: string
};

function thing(obj: SomeType) {
  const {prop = 1} = obj;

  let f1: string = prop;
  let f2: number = prop;
}

哪些错误

let f1: string = prop;
                 ^ number. This type is incompatible with
let f1: string = prop;
        ^ string
let f2: number = prop;
                 ^ string. This type is incompatible with
let f2: number = prop;
        ^ number

因为 prop 既不是数字也不是字符串,就类型系统而言,两者都是。

因此,您可以显式声明给定绑定的类型,或者编写您的代码以使推理起作用。