Flow: Using object literal with string lookup should warn about null

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

This has bitten me a couple of times recently.

Here's the minimal repro case:

/* @flow */
const a = {
  a: {i: 0},
  b: {i: 1},
};

const x = "a";
const y: string = "c";

// This one can be inferred via the literal string
a[x].i + "A";

// This one should really be ?{i: number}
// but it seems to be (unknown)
a[y].i + "A";

If I add the hint {[k: string]: ?{i: number}} onto the map then I get warned about nulls, but I lose the literal inference.

On a related note, I think the non-nullable {[k: string]: {i: number}} type should only be allowed if every key in the keyspace is defined 馃槃

hard Needs docs object model help wanted

All 3 comments

If you skip the redundant type annotation on y it works as expected.

| mobile portrait |
| :-: |

This is interesting though.
It's unexpected behaviour that having a redundant annotations breaks type checking.

The redundant type annotation was just to hide the literal value from flow - in reality that's a value of type string coming from elsewhere in the program.

@glenjamin This behavior is expected according to the current design. The question is whether to allow bracket access on object types that are not declared as dictionary types (call these strict objects). We decided to be less strict here to allow seamless looping over keys of a strict object. Might revisit decision in the future.

But for now, you can use the following workaround: Use the type { a: { i: number }, b: { i: number }, [k: string]: ?{ i: number } } on const a to get what you want.

Was this page helpful?
0 / 5 - 0 ratings