How to use/define Enums with Flow type checking? How to use/define Enums with Flow type checking? javascript javascript

How to use/define Enums with Flow type checking?


To express an enum with flow you can use $Values utility in conjunction with frozen object type:

export const LOAN_STATUS = Object.freeze({  PENDING: 'pending',  CURRENT: 'current',  DUE: 'due',  OVERDUE: 'overdue',  PENDING_PAYMENT: 'pending_payment',  CHARGED_OFF: 'charged_off',  VOIDED: 'voided',  DISPUTED: 'disputed',  REFUNDED: 'refunded',  SETTLED: 'settled',});type LoanStatus = $Values<typeof LOAN_STATUS>;export const ACTIVE_LOAN_STATUS: LoanStatus[] = [  LOAN_STATUS.OVERDUE,  LOAN_STATUS.CURRENT,  LOAN_STATUS.DUE,  LOAN_STATUS.PENDING_PAYMENT,]

This works starting from 0.60.0 version.


Here is the most concise way to achieve this:

const activeLoanStatuses = {  current: 'current',  due: 'due',  overdue: 'overdue',  pending_payment: 'pending_payment'};const otherLoanStatuses = {  pending: 'pending',  charged_off: 'charged_off',  voided: 'voided',  disputed: 'disputed',  refunded: 'refunded',  settled: 'settled',};type ActiveLoanStatus = $Keys<typeof activeLoanStatuses>;type LoanStatus = $Keys<typeof otherLoanStatuses> | ActiveLoanStatus;const activeLoanStatusesMap: { [key: LoanStatus]: ?ActiveLoanStatus} = activeLoanStatuses;if (activeLoanStatusesMap[loan.status]) {}


While incredibly verbose, and non-scalable, this falls into Flow's "Disjoint Unions" case and such can be implemented using ===. As they mention on that page, Case Analysis is done via that operator, as javascript naturally does with switch-case statements.

In your case, that equates to:

switch(loan.status) {  'pending':  'current':  'due':  'overdue':  'pending_payment':  'charged_off':  'voided':  'disputed':  'refunded':  'settled':    // your behavior here}

As I mentioned, this is highly verbose in code which uses your types, but to counter that, it has the benefit of defining your types without creating a boilerplate object- you simply define your literal options and union them together (your second implementation).

This has the obvious downside of coupling your type definition with your implementations of its consumers, so use with caution.