Reputation: 2487
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.
Why does this happen?
Upvotes: 1
Views: 2103
Reputation: 3201
As noted by @TLadd, it does appear to be a bug.
The problem is specifically with using null
as a permitted type when object destructuring with a default value.
$FlowFixMe
can be used to suppress the error, to avoid mangling your code, or you could create your own suppression e.g. $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.
Here are some alternatives which might fit your use case (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.
Upvotes: 2
Reputation: 6884
It's a bug in flow. 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);
}
Upvotes: 2