Flow: Support optional properties in objects

Created on 19 Nov 2014  路  9Comments  路  Source: facebook/flow

If I have the following type:

type MyType = {
  a: ?any;
  b: ?any;
}

And the following instance of it:

var myThing : MyType = {
  a: 'hello'
};

Flow will find the following error:

/Users/tboyt/Coding/mode7/src/Foo.js:2:15,5:1: property b
Property not found in
  /Users/tboyt/Coding/mode7/src/Foo.js:7:24,9:1: object literal

This makes sense, given that the maybe type is intended to be either the given type or null, not the type or undefined. However, not being able to define a property as entirely optional - e.g., being either a specific type or undefined - seems like a big missing feature.

For an example use case, imagine an API with a constructor that uses a hash of keyword arguments, most of which are optional. It would be great to be able to enforce the types of those arguments, _if present_, using Flow, and ignore missing arguments.

feature request

Most helpful comment

I know this is an old issue but just in case someone else is curious about the comment of @romulof you have to type the object like so:

const config : Object = {
  baseURL: "apiUrl",
};

and no more error voila

All 9 comments

You can do b: null or b: undefined in the myThing literal to get by.

We may support optional property syntax in types, like so { a: ?any; b?: any } to let you omit properties, like you can omit arguments when parameters are declared optional. So that would typecheck your code as is.

There is a difference between optional properties and nullable properties.

{ b?: String } means if the b property exist then enable that feature with the string argument.

{ b: String | null } means if the b property does not exist then default its value and use the feature.

One is for optional features, the other is for default values.

+1

As for v0.4 this issue seems fixed:

/* @flow */

var x: {a?: string;} = {}; // ok!

Can this be closed?

Closing. Please reopen if this is still an issue.

const config = {
  baseURL: apiUrl,
};

if (accessToken) { // <-- property `headers`. Property not found in object literal
  config.headers = {
    Authorization: `Bearer ${accessToken}`,
  };
}

Do I have to manually add type hints to config to suppress this error message?

I know this is an old issue but just in case someone else is curious about the comment of @romulof you have to type the object like so:

const config : Object = {
  baseURL: "apiUrl",
};

and no more error voila

I know this is old, but am running into the case where I am checking a property that does not exist in a flow type.

var x: {a?: string;} = {}; // ok!
if (x.b ==="something") { 
  // do something
}

I think it would be helpful if this also gave an error.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

bennoleslie picture bennoleslie  路  3Comments

cubika picture cubika  路  3Comments

Beingbook picture Beingbook  路  3Comments

ghost picture ghost  路  3Comments

iamchenxin picture iamchenxin  路  3Comments