Flow: Improve support of property existance checking

Created on 6 Apr 2019  路  9Comments  路  Source: facebook/flow

Flow version: ALL

Expected behavior

  • if (prop in obj) console.log(obj[prop]) should work
  • if (typeof obj[prop] !== "undefined") console.log(obj[prop]) should work
  • if (obj[prop] !== undefined) console.log(obj[prop]) should work
  • if (obj[prop]) console.log(obj[prop]) should work

Actual behavior

There is no way to check if a property exist without getting an error

  • Link to Try-Flow or Github repo: Try Flow
refinements enhancement

Most helpful comment

I'd be interested in an idiomatic way to refine types when we're not in control of what arguments we get. Disjoint unions on some sort of type property are all well and good, but we don't always have the luxury. I don't really mind if it requires some extra annotation trickery, but I should be able to tell flow, "Hey I _know_ this prop isn't on one part of the union, _that's literally why I'm checking this prop;_ I'm trying to do a runtime refinement."

Right now I don't see a way to do that without jumping through a bunch of data-transformation hoops and variable-juggling that make the code much harder to read and maintain.

All 9 comments

@mgtitimoli you don't have idle in object type

Try Flow

They all work except for in check

@goodmind you specified a type to messages making idle optional, that way for sure there is no gonna be an error.

The problem is that currently Flow does not provide a way to check the existance of a key on an object without a type, I would expect this not to be an error and just be another case of refinement.

What type would it refine to if you were allowed to test a property that isn't present in the object?

A foo?: number, property would be number | undefined, but if you test it with e.g. if (obj.foo != null) it should refine to just number inside the conditional. Defining it as optional is what enables the refinement, but without having specified the property you aren't allowed to access it at all (which helps catch errors like typos causing you to inadvertently test a non-existent property on the object)

@FireyFly have you seen my example?

Let me rephrase the question, If you have a set of 3 keys all typed, and you have an object which only has entries with 2 keys of the set, is there a way I can tell Flow by using a condition with the set that would result in a subset with only the keys that object has?

@mgtitimoli you can only check for optional fields in object

because there is no need to check for properties that are not allowed by type

untyped objects are considered sealed and are not allowed to have any extra properties

so you don't need to check for those extra properties

@thecotne let's say I have a fn that receives a key that it's a disjoint of 3 possible values, and then I have an object which has 2 entries with keys of the disjoint, I would like to test if the given key is in the object to do something. This is what the issue is about, and I imo it's a pretty common pattern.

I'd be interested in an idiomatic way to refine types when we're not in control of what arguments we get. Disjoint unions on some sort of type property are all well and good, but we don't always have the luxury. I don't really mind if it requires some extra annotation trickery, but I should be able to tell flow, "Hey I _know_ this prop isn't on one part of the union, _that's literally why I'm checking this prop;_ I'm trying to do a runtime refinement."

Right now I don't see a way to do that without jumping through a bunch of data-transformation hoops and variable-juggling that make the code much harder to read and maintain.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

funtaps picture funtaps  路  3Comments

marcelbeumer picture marcelbeumer  路  3Comments

bennoleslie picture bennoleslie  路  3Comments

cubika picture cubika  路  3Comments

pelotom picture pelotom  路  3Comments