Reputation: 15471
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
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