interface PlainConfigItem { type : 'group' | 'color' | 'string' | 'boolean' | 'number' ; dflt ? : any ; min ? : number ; max ? : number ; reconfigurable ? : boolean | string ; values ? : unknown ; documentation ? : string ; } interface GroupConfigItem extends PlainConfigItem { type : 'group' ; values : Record < string , PlainConfigItem > ; } class Type < A > { dflt : A ; reconfigurable : boolean | string ; documentation : string ; constructor ( dflt , reconfigurable , documentation ) { this . dflt = dflt ; this . reconfigurable = reconfigurable ; this . documentation = documentation ; } } internal export class Numeric extends Type < number > { min : number ; max : number ; type = 'number' ; constructor ( { dflt , min , max , reconfigurable , documentation , } ) { super ( dflt , reconfigurable , documentation ) ; this . min = min ; this . max = max ; } } internal export type ConfigItem = PlainConfigItem | Numeric ; function isGroupConfigItem ( item ) { return item . type === 'group' ; } internal export function configMap < Conf > ( mapper , cfgMetadata ) { return Object . assign ( { } , ... Object . entries ( cfgMetadata ) . map ( ( [ k , v ] ) => { if ( isGroupConfigItem ( v ) ) { return { [ k ] : configMap < Conf > ( mapper , v . values ) } ; } return { [ k ] : mapper ( v ) } ; } ) ) ; }