简体   繁体   English

流-可能类型与看似有效的默认对象参数不兼容

[英]Flow - maybe types incompatible with seemingly valid default object parameters

Consider the code: 考虑一下代码:

// @flow
type Params = {
  value: ?number,
}
function acceptsMaybeNumber({

  // Error:(6, 3) null or undefined [1] is incompatible with number [2].
  // value = 4 // <--- DOESN'T WORK

  // Error:(7, 3) null or undefined [1] is incompatible with number [2].
  // Error:(7, 11) null [1] is incompatible with number [2].
  // value = null // <--- DOESN'T WORK

  // Error:(15, 3) null or undefined [1] is incompatible with number [2].
  // Error:(16, 11) undefined [1] is incompatible with number [2].
  // value = undefined // <--- DOESN'T WORK

  value // <-- WORKS
}: Params) {
  console.log(value);
}

Since the value key in Params type accepts number , null , and undefined types, setting the default value of this key to either of those should be valid but instead throws the below errors. 由于Params类型的value键接受numbernullundefined类型,因此将此键的默认值设置为其中一个应该有效,但会引发以下错误。

Why does this happen? 为什么会这样?

It's a bug in flow. 这是流程中的错误。 https://github.com/facebook/flow/issues/183#issuecomment-358607052 . https://github.com/facebook/flow/issues/183#issuecomment-358607052 Easiest fix is probably to just not rely on the default destructuring value. 最简单的解决方法可能就是不依赖默认的解构值。 So something like 所以像

type Params = {
  value?: ?number,
}
function acceptsMaybeNumber(params: Params) {
  const value = typeof params.value === 'number' ? params.value : 4
  console.log(value);
}

As noted by @TLadd, it does appear to be a bug . 正如@TLadd指出的那样,它的确似乎是一个bug

The problem is specifically with using null as a permitted type when object destructuring with a default value. 问题特别是在使用默认值进行对象销毁时使用null作为允许的类型。

$FlowFixMe can be used to suppress the error, to avoid mangling your code, or you could create your own suppression eg $FlowDestructuringDefaultBug . $FlowFixMe可以用于抑制错误,避免$FlowFixMe代码,或者可以创建自己的抑制器,例如$FlowDestructuringDefaultBug NB: You need to put the $Flow suppression comment on the line immediately preceding the default assignment, so you need to break your parameters across multiple lines as you did in your original example. 注意:您需要在默认赋值之前的行上添加$ Flow抑制注释,因此您需要像在原始示例中那样在多行中破坏参数。

Here are some alternatives which might fit your use case ( Try ): 以下是一些适合您的用例的替代方法( Try ):

// @flow
type MaybeParams = {
  value: ?number,
}
function acceptsMaybeNumber({
  // originalValue = 1  // FAIL
  // $FlowFixMe
  value = 1,            // PASS (but not in Try where $FlowFixMe is disabled)
}: MaybeParams) {
  console.log(value);
}

type OptionalParams = {
  value?: number,
}
function acceptsOptionalNumber({
  value = 1,                // PASS
}: OptionalParams) {
  console.log(value);
}

acceptsOptionalNumber({ })  // PASS


type UndefinedParams = {
  value: void | number,
}
function acceptsUndefinedNumber({
  value = 1,                // PASS
}: UndefinedParams) {
  console.log(value);
}

acceptsUndefinedNumber({ value: undefined })    // PASS

If you specifically want to handle null as a permitted, specified value, then you'll have to avoid the default value assignment in the destructuring. 如果您特别想将null作为允许的指定值进行处理,则必须避免在解构中分配默认值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM