Flow: "property not found in object literal" using dot notation and computed properties

Created on 27 May 2016  路  7Comments  路  Source: facebook/flow

I'm getting property not found in object literal with the following code:

const API = {
  TYPE: 'foo'
};
API.someMethod = function() { // property 'someMethod' Property not found in object literal
  ...
};

However, if I change the code slightly, the error goes a way:

const API = {};
API.TYPE = 'foo';
API.someMethod = function() { // this is ok
  ...
};

What am I doing wrong in the first example? What is it that Flow is flagging as a problem?

Needs docs object model

Most helpful comment

Answering my own question. It could be:

const route: Object = { // ... }

More options in #1606

All 7 comments

From docs:

When object types appear as annotations, they are considered sealed. Also, non-empty object literals are considered to have sealed object types. In fact, the only cases where an object type is not sealed are when it describes an empty object literal (to be extended by adding properties to it), an object literal with spread properties, or when it describes a map (see below).

@vkurchatkin thank you, that makes sense. I think it'd be useful if the error message included something about the object literal being a sealed object.

@vkurchatkin I ran into the same error for a slightly different use case, using computed properties:

const HTTP = {
  [HttpMethods.GET]: {},
  [HttpMethods.POST]: {},
  ...
};
HTTP.GET.doGet = function() {...} // property GET not found in object literal
HTTP.POST.doPost = function() {...} // property POST not found in object literal

Is this expected behavior? Is Flow correctly interpreting the object literal with computed properties?

OMFG. I struggled with this for a day.

Turns out that changing this:

export function makeResponse (
  event: EvType,
  data?: JSONType,
  err?: (string | {message: string})
) : Response {
  var response = {event}
  if (event === EVENT_TYPE.ERROR) {
    if (err) {
      response.data = data
      response.err = err
    } else {
      response.err = data
    }
  } else {
    response.data = data
  }
  return response
}

To this:

export function makeResponse (
  event: EvType,
  data?: JSONType,
  err?: (string | {message: string})
) : Response {
  var response: Response = {event} // <-- !!!! bs!!
  if (event === EVENT_TYPE.ERROR) {
    if (err) {
      response.data = data
      response.err = err
    } else {
      response.err = data
    }
  } else {
    response.data = data
  }
  return response
}

Made the nonsensical error go away. Of course it's a response type! It's what's being returned and that's clearly annotated in the function definition. Surprised Flow couldn't figure that out on its own and needed me to tell it.

@vkurchatkin So what am I supposed to do in the following case:

const route = {
  path,
  name,
  getComponent () {
    // ...
  }
}
if (sagas) {
  route.onEnter = function () {
    // ...
  }
  route.onLeave = function () {
    // ...
  }
}

Answering my own question. It could be:

const route: Object = { // ... }

More options in #1606

Was this page helpful?
0 / 5 - 0 ratings

Related issues

davidpelaez picture davidpelaez  路  3Comments

cubika picture cubika  路  3Comments

funtaps picture funtaps  路  3Comments

philikon picture philikon  路  3Comments

mjj2000 picture mjj2000  路  3Comments