Bruno Quaresma
Bruno Quaresma

Reputation: 10727

Flow using array values as type

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

Answers (2)

Akhil P
Akhil P

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

Jamie Dixon
Jamie Dixon

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

Related Questions