export class EnumStringHelper < T extends string > { public readonly Keys : string [ ] ; public readonly Values : T [ ] ; constructor ( protected readonly _obj , private readonly _valuesToStrings = null ) { this . Keys = Object . keys ( this . _obj ) . filter ( k => typeof this . _obj [ k as any ] === 'string' ) ; this . Values = this . Keys . map ( k => this . _obj [ k ] ) ; } keyToString ( key ) { return this . _valuesToStrings ? this . _valuesToStrings [ this . _obj [ key ] ] : key ; } valueToString ( v ) { const custom = this . _valuesToStrings && this . _valuesToStrings [ v ] ; return custom || this . _obj [ v ] ; } validateValue ( v ) { if ( ! v ) { return null ; } const i = this . Values . findIndex ( vv => vv === v ) ; return i >= 0 ? this . Values [ i ] : null ; } } export default class EnumHelper < T extends number > { public readonly Keys : string [ ] ; public readonly Values : T [ ] ; constructor ( protected readonly _obj , private readonly _valuesToStrings = null ) { this . Keys = Object . keys ( this . _obj ) . filter ( k => typeof this . _obj [ k as any ] === 'number' ) ; this . Values = this . Keys . map ( k => this . _obj [ k ] ) ; } keyToString ( key ) { const vts = this . _valuesToStrings as { [ val ] : string ; } ; return vts ? vts [ this . _obj [ key ] ] : key ; } keyToValue ( key ) { const v = this . _obj [ key ] ; return v == null ? null : v as T ; } valueToString ( v ) { const custom = this . _valuesToStrings && this . _valuesToStrings [ v ] ; return custom || this . _obj [ v ] ; } validateValue ( v ) { if ( v == null || Number . isNaN ( v ) ) { return null ; } const i = this . Values . findIndex ( vv => vv === v ) ; return i >= 0 ? this . Values [ i ] : null ; } } export class EnumBitwiseHelper < T extends number > extends EnumHelper < T > { toStrings ( value ) { return this . Keys . filter ( k => this . _obj [ k ] && this . contains ( value , this . _obj [ k ] ) ) . map ( k => this . keyToString ( k ) ) ; } toString ( value , separator = ', ' ) { const strs = this . toStrings ( value ) ; return strs . length === 0 ? this . _obj [ 0 ] : strs . join ( separator ) ; } contains ( base , target ) { return ( base & target ) === target ; } combine ( ... values ) { let res = 0 ; values . forEach ( v => { res |= v ; } ) ; return res ; } add ( value , other ) { return value | other ; } remove ( value , other ) { return value & ~ other ; } }