Pool interface 
Pools are used internally for storing mapped concrete implementations of interfaces that have multiple implementations. Pool key maps used for IDE type hinting.
ts
interface PoolKeyMap<T> {
  [key: string]: T;
}
interface Pool<T, M extends PoolKeyMap<T> = PoolKeyMap<T>> {
  has(key: keyof M | string): boolean;
  get<K extends keyof M | string>(key: K): K extends keyof M ? M[K] : T;
  add<K extends keyof M | string>(
    key: K,
    item: K extends keyof M ? M[K] : T,
    replace?: boolean
  ): void;
  remove(key: keyof M | string): void;
  keys(): (keyof M | string)[];
  items(): T[];
}Generic types are:
T- common type of entities in pool.M- map of pool keys and entity type which may be same asT, or more concrete type.
Methods 
has() 
- Param: 
key: keyof M | string - Returns: 
boolean 
Checks if pool has item by given key.
get() 
- Param: 
key: keyof M | string - Returns: 
M[K] | T- entity of dedicated type. 
Returns pool item by given key. Throws RangeError if item by given key was not found.
add() 
- Params: 
- key: 
keyof M | string - item: 
M[K] | T- entity of dedicated type. - replace?: 
boolean- set totrueif want to replace item, already registered by given key. 
 - key: 
 
Adds item to pool by given key. If given key is already registered in pool and replace param is not set to true, throws TypeError.
remove() 
- Param: 
key: keyof M | string 
Removes item from pool by given key. If given key is not found in pool, does nothing.
keys() 
- Returns: 
(keyof M | string)[] 
Returns array of pool keys.
items() 
- Returns: 
T[] 
Returns array of pool items.
