import { isObject , isNil , isString , isEmpty } from 'lodash-es' ; /**
 * Helper for creating and querying Dictionaries.
 * A wrapper around ES6 Maps.
 */ export class Dictionary < T > { protected _items : Map < string , T > ; constructor param { object } items constructor ( items ? ) { if ( isNil ( items ) ) { this . _items = new Map ( ) ; } else if ( items instanceof Set ) { throw new TypeError ( `Invalid type of argument: Set` ) ; } else if ( items instanceof Map ) { this . _items = new Map ( items ) ; } else if ( Array . isArray ( items ) ) { this . _items = new Map ( items ) ; } else if ( isObject ( items ) ) { this . _items = new Map ( ) ; for ( const key of Object . keys ( items ) ) { this . _items . set ( key , items [ key ] ) ; } } else { throw new TypeError ( `Invalid type of argument: ${ typeof items }` ) ; } } param { string } key return { object } get ( key ) { return this . _items . get ( key ) ; } param { string } key param { object } value return { object } set ( key , value ) { this . _validateKey ( key ) ; this . _items . set ( key , value ) ; return value ; } param { string } key return { object } delete ( key ) { if ( ! this . has ( key ) ) { throw new ReferenceError ( `Key: ${ key } not found.` ) ; } let value = this . _items . get ( key ) ; this . _items . delete ( key ) ; return value ; } /**
     * Clears the dictionary.
     */ clear ( ) { this . _items . clear ( ) ; } param { string } key return { boolean } has ( key ) { this . _validateKey ( key ) ; return this . _items . has ( key ) ; } return { array } keys ( ) { return Array . from ( this . _items . keys ( ) ) ; } return { array } values ( ) { return Array . from ( this . _items . values ( ) ) ; } return { object } clone ( ) { return new Map ( this . _items ) ; } return { number } get count ( ) : number { return this . _items . size ; } private _validateKey ( key ) { if ( ! isString ( key ) || isEmpty ( key ) ) { throw new TypeError ( 'Key needs to be a string' ) ; } } }