Flow: Feature request: flow should type check strict equality (`===`)

Created on 29 Aug 2016  路  4Comments  路  Source: facebook/flow

I'd like to formalize a request for the feature mentioned in this closed issue: https://github.com/facebook/flow/issues/1584

I have already run into an issue where I was using strict equality checking where I thought I was comparing two instances of the same type, but was in fact not doing so due to some deeply nested references. I.E. my if statement was something like:

if (foo.bar.baz.x.y === something.else.z)

but should have been:

if (foo.bar.baz.x.y.z === something.else.z)

I only caught the problem at run time, but I expected flow to warn me, which it correctly does if I switch over to ==. Perhaps this could be an advanced .flowconfig setting if this is not what is considered standard in Flow philosophy.

wishlist

Most helpful comment

@denisgrenader Sorry you ran into an issue with === with mismatched types. Just to clarify the design intent here: == is deemed unsafe to do with mismatched types because there's a lot of implicit conversion when the types don't match, which users often don't expect. In contrast, === is "safe" in that it is more predictable.

Now, one could make a case that for some pairs of mismatched types that are guaranteed to be non-overlapping, === is guaranteed to return false, in which case the block under the if is unreachable, and we could warn there. However we shouldn't warn when (say) a number is being compared with a number | string...indeed, if we did we would severely regress some legitimate patterns.

All 4 comments

@denisgrenader Sorry you ran into an issue with === with mismatched types. Just to clarify the design intent here: == is deemed unsafe to do with mismatched types because there's a lot of implicit conversion when the types don't match, which users often don't expect. In contrast, === is "safe" in that it is more predictable.

Now, one could make a case that for some pairs of mismatched types that are guaranteed to be non-overlapping, === is guaranteed to return false, in which case the block under the if is unreachable, and we could warn there. However we shouldn't warn when (say) a number is being compared with a number | string...indeed, if we did we would severely regress some legitimate patterns.

@avikchaudhuri, thanks for the reply. I am not sure I understand the legitimate patterns or what examples there are where flow should not warn the user of unsafe comparisons. For example comparing number to number | string to me seems like a warning because you can end up comparing mismatched types at run time, that is to say it's up to the user to explicitly coerce a potential string to a number before executing the comparison. Is there some documentation I can reference for these legitimate patterns?

If your codebase is 100% Flow, is it reasonable to use == instead of ===?

  • Flow protects you from the type coercion that == is usually discouraged for
  • == avoids problems like the one @denisgrenader describes in the OP
  • You get to type 33% less =s 馃槈

I'm also curious what the legitimate use cases are for === working like it does. Can someone spell them out?

As a guess, I suppose Flow wants this comparison to be possible (a: number) === (b: ?number) without having to refine the type of b first?

It will be well when the flow will be warned of the types that do not have common parts:

function foo(x: ?number, y: string): bool {
  return x === y;
}

function test2(x: 'variant1' | 'variant2', y: 'ver1' | 'ver2') : bool {
  return x === y;
}

foo(32, "das")
test2('variant1', 'ver1');

foo and test2 always return false.
Such comparisons are not intended and are as result of programmer error.

Was this page helpful?
0 / 5 - 0 ratings