Abraham P
Abraham P

Reputation: 15471

Object type with partial definition flowjs

Say I had a function:

const example = (item : ?{+type?: ?string}) : {+result: ?string} => {
  const state = {}
  state.result = item.result
  return state
}

This fails to typecheck with:

 12:         state.result = item.result
                                    ^^^^^^^ property `result`. Property not found in
 12:         state.result = item.result
                             ^^^^^^ object type

Why doesn't this typecheck? I did not define the type with the exact object type notation ?{|+type?: ?string|}, so shouldn't it allow additional keys? How does the exact object notation work then? And how can I define partial object types like this? Is that even possible?

Upvotes: 1

Views: 877

Answers (1)

Peter Hall
Peter Hall

Reputation: 58725

It sounds like you are trying to encode in types that the argument item can have any properties. This sounds like a map, which Flow encodes with:

{ [key: KeyType]: ValueType };

Your example can be updated like this:

const example = (item : ?{[key: string]: string}) : {+result: ?string} => {
  const state = {}
  if(item)
  {
     state.result = item.result;
  }
  return state
}

Note, you have to do a null check on item or else it won't typecheck, since you declared it as nullable in the function signature.

If there are certain required properties of item then you can use an intersection type to add that constraint. I'll create a new type for that, so it's easier to read the signature:

type Item = {[key: string]: string} & {type: string}

const example = (item : ?Item) : {+result: ?string} => {
  const state = {}
  if(item)
  {
     state.result = item.result;
  }
  return state
}


example({type: 'blah', x: '2'}); // OK
example({'blah', x: '2'}); // Error: type is missing

Upvotes: 1

Related Questions