For instance, imagine having the following list of items:
const items = [
{
key: "amalgama"
},
{
key: "torin"
},
{
key: "mascarpone"
}
]
What Flow type ItemsKeyTuple
definition should be to get the following check?
type ItemsKeyUnion = ...some stuff with items...
// so I would get the same to the following:
// type ItemsKeyUnion = “amalgama” | “torin” | “mascarpone”;
let a: ItemsKeyTuple;
a = "amalgama" // OK;
a = "tomatoes" // ERROR;
The main idea is to get instant check and help when using inside if-else, switch statements, taking into account a possibility to change keys in some moment in future and be sure that I would be noticed with Flow
about places I need to adjust.
For this to work, you would have to infer the tuple's key
values as literal string types. Unfortunately, this doesn't seem to be possible in Flow (unlike TypeScript), see facebook/flow#2639. One of the workarounds would be to use an object type, utilizing the $Keys
utility:
const dict = {
"amalgama": {},
"torin": {},
"mascarpone": {},
};
type ItemsKeyTuple = $Keys<typeof dict>;
const items = Object.keys(dict).map((key) => ({ key }));
Then, you can use Object.keys
to convert the dict into the original items
array at runtime. Notice that I have subtly used {}
as a value for the keys in dict
. This is because if you have more properties other than key
, you can put them in this empty object:
const dict = {
"amalgama": { foo: 42 },
"torin": { bar: true },
"mascarpone": { baz: "hello" },
};
type ItemsKeyTuple = $Keys<typeof dict>;
const items = Object.keys(dict).map((key) => ({ key, ...dict[key] }));