Reputation: 10727
I have an array with the values:
const currencies = ['USD', 'BRL', 'EUR']
// The true array has more then 15 currencies values
I want to avoid doing this to avoid code duplication:
type Currencies = 'USD' | 'BRL' | 'EUR'
Is it possible to use those values as types? I tried to do that:
type Currencies = $Values<currencies>
But I got an error because $Values are only for objects.
What is the best way of not duplicating the code since I already have those values in an array.
Upvotes: 3
Views: 1498
Reputation: 1620
Jamie's version will create another object currenciesObj
which is just created for the purpose of types and will stay in the code even types removed while minifying the code.
Below is the code that doesn't need creating a new object.
const xs: Array<'hi' | 'bye'> = ['hi', 'bye'];
type ArrayValues<TArr> = $Call<<T>(Array<T>) => T, TArr>;
("hi": ArrayValues<typeof xs>); // OK
("foo": ArrayValues<typeof xs>); // ERROR, "foo" not in 'hi' | 'bye'
(1: ArrayValues<typeof xs>); // ERROR, number is incompatible with string
Upvotes: 0
Reputation: 54021
As far as I can tell there isn't a way to do this currently with flow using an array.
One approach is to turn your array into an object and use $Keys
with typeof
const currencies = ['USD', 'BRL', 'EUR'];
const currenciesObj = currencies.reduce((agg, next) => ({...agg, [next]: true}), {});
type Currencies = $Keys<typeof currenciesObj>;
Upvotes: 1